使用和优势
1.省略了上下文的切换
课外扩展:
int availableProcessors = Runtime.getRuntime().availableProcessors();
System.out.println("可用的处理器: "+availableProcessors);
线程池的优势,特点
线程三种实现方法:
1.继承Thread类,不可以抛异常,无返回值
public class MyThread extends Thread{
@Override
public void run() {
super.run();
}
}
2.实现Runable的方法,不可以抛异常,无返回值
public class myRunnable implements Runnable{
@Override
public void run() {
}
}
3.实现Callable接口:会抛异常,有返回值
public class MyCallable implements Callable<Integer>{
@Override
public Integer call() throws Exception {
return null;
}
}
因为Thread的构造方法里面没有Callable接口参数。所以java采取适配器模式,使用即实现Runnable又实现callable的类,传递给Thread。所以用到了FutureTask类,它实现了Runable接口,而且它的构造方法传入的是实现Callable的类
为什么要用Callable,不用原来的Runnable与Thread?
并发和异步导致Callable出现
可以把一个主线程上面的多个任务,抽出可能堵塞的任务,到最后再于不堵塞的任务进行结合
futureTask.get() 建议放在最后
get() 表示获得最后的callable的计算结果,如果没有计算完成会强求,导致堵塞,直到计算完成
实例一:
package com.example.demo.threads;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class ThreadTest {
public static void main(String[] args) throws ExecutionException, InterruptedException {
MyCallable myCallable = new MyCallable();
//FutureTask是Runnable与Callable的一个桥梁
FutureTask<Integer> futureTask = new FutureTask<>(myCallable);
//创建一个线程 传入FutureTask类型的Callable
Thread thread = new Thread(futureTask);
thread.start();
//本来1000+100在一个线程里面,但是100这个结果可能要进行复杂的运算会堵塞,则抽出一个线程进行处理,最后再进行合并
int step1 = 1000;
System.out.println("合并之后的结果: "+(step1+futureTask.get()));
}
/**
* Thread的方式三
*/
public static class MyCallable implements Callable<Integer>{
/**
* 返回的定义的泛型
* @return
* @throws Exception
*/
@Override
public Integer call() throws Exception {
System.out.println("进入MyCallable的call");
return 100;
}
}
}
注意:多个Thread计算同一个FutureTask,那么之后计算一次,call只会进去一次。
package com.example.demo.threads;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class ThreadTest {
public static void main(String[] args) throws ExecutionException, InterruptedException {
MyCallable myCallable = new MyCallable();
//FutureTask是Runnable与Callable的一个桥梁
FutureTask<Integer> futureTask = new FutureTask<>(myCallable);
//创建一个线程 传入FutureTask类型的Callable
Thread thread = new Thread(futureTask);
thread.start();
Thread thread1 = new Thread(futureTask);
thread1.start();
//返回值为null也不会报错,而是返回null
System.out.println("callable的返回值: "+futureTask.get());
}
/**
* Thread的方式三
*/
public static class MyCallable implements Callable<Integer>{
/**
* 返回的定义的泛型
* @return
* @throws Exception
*/
@Override
public Integer call() throws Exception {
System.out.println("进入MyCallable的call");
return 100;
}
}
}
执行结果
进入MyCallable的call
callable的返回值: 100