Java学习笔记-多线程实现方式
(注意:线程开启不一定立即执行,由CPU调度执行)
1、继承Thread类
- 自定义线程类继承Thread类
- 重写run()方法,编写线程执行体
- 创建线程对象,调用start()方法启动线程
public class Test extends Thread{
@Override
public void run(){ //重写run方法
for(int i = 0; i < 50; i ++){
System.out.println("这是线程1执行的第" + i + "次");
}
}
public static void main(String[] args){
Test t1 = new Test();
t1.start(); //调用start()方法启动线程
for(int i = 0; i < 200; i ++){
System.out.println("这是主程序执行的第" + i + "次");
}
}
}
由上述例子我们会发现每次执行的结果都是不同的,有可能会主程序中穿插着线程1执行的输出,有可能先显示完主程序执行的再显示线程1执行的等等,当然,这也代表着这两个线程的执行是同步的。
不建议使用:避免OOP单继承局限性
2、实现Runnable(推荐使用)
- 定义My Runnable类实现Runnable接口
- 实现run()方法,编写线程执行体
- 创建线程对象,调用start()方法启动线程
public class TestRunnable implements Runnable{
@Override
public void run(){ //重写run方法
for(int i = 0; i < 50; i ++)
System.out.println("这是线程1执行的第" + i + "次");
}
public static void main(String[] args){
TestRunnable t1 = new TestRunnable();
new Thread(t1).start(); //传入目标对象 + Thread对象.start()
for(int i = 0; i < 200; i ++)
System.out.println("这是主程序执行的第" + i + "次");
}
}
在这个例子中最终呈现的效果和上一个方式一模一样,但这种方式更推荐使用,因为这避免了单继承的局限性,灵活方便,方便同一个对象被多个线程使用
3、实现callable接口
- 实现callable接口,需要返回值类型
- 重写call()方法,需要抛出异常
- 创建目标对象
- 创建执行服务:ExecutorService es = Executors.newFixedThreadPool(nThreads);
- 提交执行:Future result1 = es.submit(执行的对象);
- 获取结果:boolean r1 = result1.get();
- 关闭服务:es.shutdown();
public class TestCallable implements Callable<Boolean> { //实现Callable<返回值类型>接口
@Override
public Boolean call() { //重写call()方法
for (int i = 0; i < 50; i++) {
System.out.println("这是线程1执行的第" + i + "次");
}
return true;
}
public static void main(String[] args) {
TestCallable tc = new TestCallable(); //创建目标对象
ExecutorService es = Executors.newFixedThreadPool(1); //创建执行服务
Future<Boolean> result1 = es.submit(tc); //提交执行
for (int i = 0; i < 200; i++) {
System.out.println("这是主程序执行的第" + i + "次"); //主程序中执行
}
try {
boolean rs1 = result1.get(); //获取结果
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} finally {
es.shutdown(); //关闭服务
}
}
}