方法一:实现Callable接口
public class TestThread2 {
@Test
public void test1(){
FutureTask futureTask = new FutureTask(new ThreadD());
new Thread(futureTask).start();
try {
//如果不想得到返回值,下面两边可以省略
Object o = futureTask.get();
System.out.println(o);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
class ThreadD implements Callable{
@Override
public Object call() throws Exception {
String str = "fj";
return str.length();
}
}
也可以在Callabe接口中指定泛型类型,
FutureTask类中也可以指定泛型类型
方法二:Executors创建线程池
开发中常用
以下面代码为例,线程池创建了两个线程,实际有四个获取线程连接的请求,先有两个请求获得连接以后,开始执行线程运行,两个线程run方法结束后,就把连接给了其余两个请求,但是之前两个线程并没有死亡,等待这两个线程执行完run方法后,就有四个未死亡的线程,所有最后必须service.shutdown(),不然程序无法终止
public class ThreadPoolTest {
@Test
public void test1(){
ExecutorService service = Executors.newFixedThreadPool(2);
//线程池创建了2个线程,而这里开了4个,先得到的线程执行完还给线程池,再让别的线程用
ThreadE threadE = new ThreadE();
service.execute(threadE );
service.execute(threadE );
service.execute(threadE );
service.execute(threadE );
//关闭线程池
service.shutdown(); //如果不手动进行此操作,创建的线程全都无法死亡,即每个线程无法消亡
}
}
class ThreadE implements Runnable{
@Override
public void run() {
System.out.println("业务逻辑 当前线程:"+Thread.currentThread().getName());
}
}
结果:
业务逻辑 当前线程:pool-1-thread-1
业务逻辑 当前线程:pool-1-thread-2
业务逻辑 当前线程:pool-1-thread-1
业务逻辑 当前线程:pool-1-thread-2
补充:可以通过创建不同的类重写run方法或call方法来实现不同业务逻辑,即多个不同的ThreadE
上述service也可以调用submit(Callable)方法实现
public class ThreadPoolTest {
@Test
public void test1(){
ExecutorService service = Executors.newFixedThreadPool(2);
ThreadF threadF = new ThreadF();
service.execute(threadF );
service.execute(threadF);
service.execute(threadF );
service.execute(threadF );
service.shutdown(); //如果不手动进行此操作,创建的线程全都无法死亡,即每个线程无法消亡
}
}
class ThreadF implements Callable {
@Override
public Object call() throws Exception {
System.out.println("业务逻辑 当前线程:"+Thread.currentThread().getName());
return null;
}
}
线程池如何进行线程管理?
在上述代码基础上
@Test
public void test1(){
ExecutorService service = Executors.newFixedThreadPool(2);
//通过service.getClass()知道了ExecutorService具体实现类是ThreadPoolExecutor
ThreadPoolExecutor service2 = (ThreadPoolExecutor) service;
//对线程池及线程进行管理
service2.setCorePoolSize(20);
service2.setMaximumPoolSize(500);
ThreadF threadF = new ThreadF();
service.execute(threadF );
service.execute(threadF);
service.execute(threadF );
service.execute(threadF );
service.shutdown();
}
根据阿里开发手册,不允许使用Executors类,原因如下:
正确写法是自己new ThreadPoolExecutor类,加入参数
public class Test1 {
public static void main(String[] args) {
ThreadPoolExecutor threadPool = new ThreadPoolExecutor(3, 5, 1,
TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(3),Executors.defaultThreadFactory()
,new ThreadPoolExecutor.AbortPolicy());
try {
for (int i = 0; i < 11 ; i++) {
threadPool.execute(() -> {
System.out.println(Thread.currentThread().getName());
});
}
} finally {
threadPool.shutdown();
}
}
}