四种方式创建java多线程
1.继承Thread类
2.实现Runnable接口
3.实现Callable接口
4.使用线程池
继承Thread类
public class Thread1 extends Thread {
@Override
public void run() {
System.out.println("i am thread1");
}
}
实现Runnable接口
public class Thread2 implements Runnable {
@Override
public void run() {
System.out.println(“i am thread2”);
}
}
实现Callable接口
public class Thread3 implements Callable<Integer> {
@Override
public Integer call() {
System.out.println("i am thread3");
return 111111;
}
}
使用线程池
ExecutorService executorService = Executors.newFixedThreadPool(10);
Future<Integer> submit = executorService.submit(new Thread3());//使用callable接口
try {
submit.get(); //可以得到callable接口中的返回值
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
executorService.execute(new Thread2());//使用runnable接口
executorService.shutdown();
区别
1.继承Thread类,其本质上也是实现了Runnable接口,而且由于Java不支持多继承,所以要是已经继承了其他父类时,就无法使用继承Thread类是方法使用多线程
class Thread implements Runnable
2.实现Runnable接口,将实现了Runnable接口的实现类放入Thread的构造函数中,赋值给target属性。
public Thread(Runnable target) {
init(null, target, "Thread-" + nextThreadNum(), 0);
}
当调用 start() 方法时,会开启线程,并自动调用run()方法。
jdk5.0之后新增了Callable和线程池来创建多线程
Callable和Runnable区别:
不同点:
两者最大的不同点是:
1.实现Callable接口的任务线程能返回执行结果;而实现Runnable接口的任务线程不能返回结果;
2/Callable接口的call()方法允许抛出异常;而Runnable接口的run()方法的异常只能在内部消化,不能继续上抛;
注意点:
Callable接口支持返回执行结果,此时需要调用FutureTask.get()方法实现,此方法会阻塞主线程直到获取‘将来’结果;当不调用此方法时,主线程不会阻塞