java中线程是经常会提到的问题,但是实际开发工作却又很少用的技术(起码本人用的比较少)。下面介绍几种常见的线程实现方式
1、继承Thread类,重写run方法
我们通过集成Thread类并通过重写run方法的方式实现线程,然后通过start方法启动线程
public class MyThread extendsThread{
@Overridepublic voidrun() {
System.out.println("================"+newDate());
}public static voidmain(String[] args) {for(int i=0;i<10;i++){
MyThread myThread= newMyThread();
myThread.start();
}
}
}
运行main方法测试效果:
2、通过实现Runable接口的方式
Thread作为java中的线程类,其有一个Runable作为构造参数的构造方法,我们可以通过实现Runable接口,从而进一步实现线程。同样是通过start启动线程。
/*** 通过实现Runable接口*/
public class MyRunableImpl implementsRunnable{privateString name;publicMyRunableImpl(String name) {this.name =name;
}
@Overridepublic voidrun() {
System.out.println(name+"================"+newDate());
}public static voidmain(String[] args) {for(int i=0;i<10;i++){
MyRunableImpl myRunable= new MyRunableImpl("myRunable"+i);
Thread t= newThread(myRunable);
t.start();
}
}
}
运行main方法测试效果:
3、通过FutureTask实现线程
此方式和第二种方式有点像,还是使用Thread(Runnable)构造方法,区别在于此处不用自己实现Runable,而是使用FutureTask。FutureTask实现了
RunnableFuture接口,而RunnableFuture接口又集成了Runable接口,所以我们也可以使用FutureTask做为构造参数创建线程。FutureTask支持两种有参的构造方法,此处我们使用Future(Callable)。首先,我们需要创建一个类,该类需要实现Callable接口,实现call方法。
public class MyCallable implementsCallable {privateString name;publicMyCallable(String name) {this.name =name;
}
@Overridepublic Object call() throwsException {
System.out.println(name+"==============="+newDate());returnname;
}
}
测试类
public classFutureTaskTest {public static void main(String[] args) throwsExecutionException, InterruptedException {for(int i=0;i<10;i++){
MyCallable myCallable= new MyCallable("myCallable"+i);
FutureTask futureTask= newFutureTask(myCallable);
Thread t= newThread(futureTask);
t.start();
Object o=futureTask.get();
System.out.println("return value============"+o);
}
}
}
运行main方法测试效果:
在线程启动时会调用Callable接口的call方法。我们可以通过FutureTask.get()方法获取call()的返回值。需要注意的是get方法会阻塞线程。
4、使用Executors创建线程池
Executors是java juc中的类,我们可以通过其创建线程池,并以此实现线程。此方式同样需要一个Callable的实现类,此处我们还是使用第3中方法中的类。
public classExecutorsTest {public static voidmain(String[] args) {
ExecutorService executorService= Executors.newFixedThreadPool(10);
List> list = new ArrayList<>();for(int i=0;i<10;i++){
MyCallable myCallable= new MyCallable("myCallable"+i);
Future submit=executorService.submit(myCallable);
list.add(submit);
}for(Future future:list){try{
Object o=future.get();
System.out.println("return value============="+o);
}catch(InterruptedException e) {
e.printStackTrace();
}catch(ExecutionException e) {
e.printStackTrace();
}
}
executorService.shutdown();
}
}
我们通过Executors创建线程池,ExecutorService.submit(Callable)启动线程。submit方法会返回一个Future对象,通过其get()方法可以获取Callable实现类的call方法返回值。执行完上述操作后需要调用ExecutorService.shutdown方法,不然主线程会一直处于运行状态。
执行main方法测试效果:
以上就是常见的创建多线程的几种方式。如果不对,对应大家评论留言。