沈汉学

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

1.线程池的概念

规定一个容器来存储线程,当有任务需要是,从中取走一个线程,用完之后归还。

2.使用线程池方式--Runnable接口

先学习两个类。

ExecutorService:线程池类。

Executors:线程池创建工厂类。

 

1.先创建一个类,实现Runnable接口,重写run()方法

1 public class MyRunnable implements Runnable {
2     @Override
3     public void run() {
4         // TODO Auto-generated method stub
5         for (int i = 1; i < 101; i++) {
6             System.out.println(Thread.currentThread().getName()+":"+i);
7         }
8     }
9 }

2.新建测试类,获取线程池对象,创建线程任务,执行任务之后销毁任务。

 1 public class demo03 {
 2     public static void main(String[] args) {
 3         //获取线程池对象
 4         ExecutorService es = Executors.newFixedThreadPool(2);//规定存储2个线程
 5         //创建线程任务对象
 6         MyRunnable mr = new MyRunnable();
 7         //线程池随机选一条空闲线程执行线程任务
 8         es.submit(mr);
 9         es.submit(mr);
10         es.submit(mr);
11         //销毁线程池
12         es.shutdown();
13     }
14 }

3.执行结果

 

可以看到,我们规定了两条线程,但开启了三个任务,所以第三个任务就会处于等待状态,等待有线程空闲之后,它再开始。

 

3.使用线程池方式—Callable接口

3.1区别

我们发现,使用Runnable接口时,重写该方法并不能有返回值且不能抛出异常,那我们要有返回值或要抛出异常时,就是用到Callable接口。

3.2使用

1.创建类,实现Callable接口,实现接口时,要表明泛型,这样在点击重写方法时会直接将该泛型的返回值写出,重写的方法上也可以添加异常。

1 import java.util.concurrent.Callable;
2 
3 public class MyCallable implements Callable<String> {
4     public String call() throws Exception {
5         return "abc";
6     }
7 }

2.创建测试类,获取线程池对象,创建线程任务对象,用Future接受执行对象的返回值。

 1 public class demo04 {
 2     public static void main(String[] args) throws InterruptedException, ExecutionException {
 3         //获取线程池对象
 4         ExecutorService es = Executors.newFixedThreadPool(2);
 5         //创建线程任务对象
 6         MyCallable mc = new MyCallable();
 7         Future<String> f = es.submit(mc);
 8         //获取返回值
 9         String mes = f.get();
10         System.out.println(mes);
11         es.shutdown();
12     }
13 }

3.执行结果

 

4.线程池练习:分别用两条线程计算1-100的和,1-200的和

1.首先,要先创建一个类继承Callable,泛型的话,因为是两束相加的结果,所以是Integer类型的

因为重写的方法并不能使用传参数的方法来获取数,所以使用另外一种,成员变量和构造方法的办法来获取数值。

 1 public class MySum implements Callable<Integer> {
 2     private int n;
 3     public MySum(){}
 4     public MySum(int n){
 5         this.n = n;
 6     }
 7     public Integer call() throws Exception {
 8         int sum = 0;
 9         for (int i = 1; i <= n; i++) {
10             sum+=i;
11         }
12         return sum;
13     }
14 }

2.创建测试类,按照顺序操作

 1 public class demo05 {
 2     //分别用两条线程计算1-100的和,1-200的和
 3     public static void main(String[] args) throws InterruptedException, ExecutionException {
 4         //获取线程池对象
 5         ExecutorService es = Executors.newFixedThreadPool(2);
 6         //创建线程任务对象
 7         MySum my1 = new MySum(100);
 8         MySum my2 = new MySum(200);
 9         //提交线程任务
10         Future<Integer> f1 = es.submit(my1);
11         Future<Integer> f2 = es.submit(my2);
12         //获取返回值
13         System.out.println(f1.get());
14         System.out.println(f2.get());
15         //销毁线程池
16         es.shutdown();
17     }
18 }

 

posted on 2021-07-26 16:02  沈汉学  阅读(42)  评论(0编辑  收藏  举报