当通过实现Callable接口创建线程时,调用了Future接口的实现类FutureTask,该类还实现了Runnable接口,所以可以让实例化对象作为Thread对象的Target。并且每次只执行一个线程的任务,当执行完线程的主任务后,返回值。
示例代码:
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class RunNewFixedThreadPool { public static void main(String[] args) { RunNewFixedThreadPool run = new RunNewFixedThreadPool(); ExecutorService executorService = Executors.newFixedThreadPool(6); for (int i = 0; i < 5; i++) {//创建五个线程 executorService.execute(run.new MyRunnable(" "+(i+1))); } for (int i = 5; i < 10; i++) {//再创建五个线程,如果当前线程池中有线程可以使用,则复用,否则创建新的线程,但是线程池中最多只能有6个线程 executorService.execute(run.new MyRunnable(" "+(i+1))); } } public class MyRunnable implements Runnable{ private String username; public MyRunnable(String username) { this.username = username; } @Override public void run() { System.out.println(Thread.currentThread().getName()+" username="+username+" begin "+System.currentTimeMillis()); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+" username="+username+" end "+System.currentTimeMillis()); } } }这里面每次创建的线程数可以设定,上面设为了5,所以一次性开启了五个线程。如果设为3,那么一次最多开三个进程,并且只有当一些进程关闭时,才会开启相同数目的进程。
总结四种创建线程的方法实现Runnable和实现Callable接口的方式基本相同,不过是后者执行call()方法有返回值,前者线程执行体run()方法无返回值,并且如果使用FutureTask类的话,只执行一次Callable任务。因此可以把这两种方式归为一种这种方式与继承Thread类的方法之间的差别如下:
1、线程只是实现Runnable或实现Callable接口,还可以继承其他类。
2、这种方式下,多个线程可以共享一个target对象,非常适合多线程处理同一份资源的情形。
3.继承Thread类只需要this就能获取当前线程。不需要使用Thread.currentThread()方法
4、继承Thread类的线程类不能再继承其他父类(Java单继承决定)。
5、前三种的线程如果创建关闭频繁会消耗系统资源影响性能,而使用线程池可以不用线程的时候放回线程池,用的时候再从线程池取,项目开发中主要使用线程池的方式创建多个线程。
6.实现接口的创建线程的方式必须实现方法(run() call())。
关于Java创建多线程的四种方式就分享到这里了,感谢各位大佬观看!