创建线程的方法总的有四种方法,之前我提过前两种一个是继承Thread方法一个是实现Runnable接口方法 现在我们接着讲第三种实现Callable接口和第四种线程池
1.创建一个实现Callable接口的实现类
2.实现call方法
3.创建Callable接口实现类的对象
4.将此接口实现类作为参数传递到FutureTask构造器中
5.将FutureTask的对象作为参数传递到Thread类的构造器中,创建Thread对象,并调用start()
实现代码如下:
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
/**
* 创建线程的第三种方法
* 实现Callable接口 jdk5.0新增
* 步骤
* 1.创建一个实现类Callable的实现类
* 2.实现Call方法
* 3.创建Callable实现类接口的对象
* 4.将此Callable接口实现类对象作为参数传递到FutureTask构造器中
* 5.将FutureTask的对象作为参数传递到Thread类的构造器中,创建Thread对象,并调用start()
* @Author:阿土伯
* @Date: 2022/1/17 11:40
* 如何理解实现Callable接口的方式创建多线程比实现Runnable接口创建多线程方式强大?
* 1.call()可以有返回值
* 2.call()可以抛出异常,被外面的操作捕获,获取异常信息
* 3.Callable是支持泛型的
*/
//1.创建一个实现类Callable的实现类
class NumThread implements Callable{
//2.实现call方法
@Override
public Object call() throws Exception {
int sum=0;
for(int i=0;i<=100;i++){
if(i%2==0){
System.out.println(i);
sum+=i;
}
}
return sum;
}
}
public class ThirdTread {
public static void main(String[] args){
//3.创建Callable接口实现类对象
NumThread numThread = new NumThread();
//4.将此Callable接口实现类对象作为参数传递到FutureTask构造器中
FutureTask futureTask=new FutureTask(numThread);
//5.将FutureTask的对象做为参数传递到Thread类的构造器中,创建Thread对象,并调用start()
new Thread(futureTask).start();
try {
Object sum = futureTask.get();
System.out.println("总和为:"+sum);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
线程池:
在开发中我们大部分使用线程池来创建线程
代码如下:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**第四种创建线程的方式:使用线程池 在开发中大部分都是用线程池的方法
* 背景:经常创建和销毁、使用量特别大的资源,比如并发情况下的线程
* 对性能影响很大
* 思路:提前创建好多个线程,放入线程池中,使用时直接获取,使用完放回
* 线程池中。可以避免频繁创建销毁、实现重复利用。
* 好处:
* 提高响应速度(减少创建新线程的时间)
* 降低资源消耗(重复利用线程池中的线程,不需要每次都创建)
* 便于管理线程
* @Author:阿土伯
* @Date: 2022/1/17 19:53
*/
class Pools implements Runnable{
@Override
public void run() {
for(int i=0;i<=100;i++){
if(i%2==0){
System.out.println(Thread.currentThread().getName()+": "+i);
}
}
}
}
public class ForthThread {
public static void main(String[] args) {
//提供指定线程数量的线程池
ExecutorService service=Executors.newFixedThreadPool(10);
//设置线程池的属性
//2.执行指定的线程的操作。需要提供Runnable接口或Callable接口实现类对象
service.execute(new Pools());//适合适用Runnable
// service.submit();//适合适用于Callable
service.shutdown();
}
}