使用线程池实现卖票

1:先写一个Runnable。

 1 package ThreadPool;
 2 
 3 /**
 4  * @ProjectName: smartdata
 5  * @Package: ThreadPool
 6  * @ClassName: TicketRunnable
 7  * @Author: heluwei
 8  * @Description:
 9  * @Date: 2020/3/23 18:55
10  * @Version: 1.0
11  */
12 public class TicketRunnable implements Runnable {
13 
14     // 为了保持票数的一致,票数要静态
15     static int tick = 20;
16     // 创建一个静态钥匙
17     static Object ob = "aa";//值是任意的
18     // 重写run方法,实现买票操作
19     @Override
20     public void run() {
21         while (tick > 0) {
22             synchronized (ob) {// 这个很重要,必须使用一个锁,
23                 // 进去的人会把钥匙拿在手上,出来后才把钥匙拿让出来
24                 if (tick > 0) {
25                     System.out.println(Thread.currentThread().getName() + "卖出了第" + tick + "张票");
26                     tick--;
27                 } else {
28                     System.out.println("票卖完了");
29                 }
30             }
31             try {
32                 Thread.sleep(1000);//休息一秒
33             } catch (InterruptedException e) {
34                 e.printStackTrace();
35             }
36         }
37     }
38 
39 }

二:使用线程池进行操作

 1 package ThreadPool;
 2 
 3 import java.util.ArrayList;
 4 import java.util.List;
 5 import java.util.concurrent.ArrayBlockingQueue;
 6 import java.util.concurrent.ThreadPoolExecutor;
 7 import java.util.concurrent.TimeUnit;
 8 
 9 /**
10  * @ProjectName: smartdata
11  * @Package: ThreadPool
12  * @ClassName: ThreadPoolExecutorDemo
13  * @Author: heluwei
14  * @Description: ThreadPoolExecutor线程池
15  * @Date: 2020/3/21 20:35
16  * @Version: 1.0
17  */
18 public class ThreadPoolExecutorDemo {
19     private static final int CORE_POOL_SIZE = 5; //核心线程数为 5
20     private static final int MAX_POOL_SIZE = 10; //最大线程数 10
21     private static final int QUEUE_CAPACITY = 100; //
22     private static final Long KEEP_ALIVE_TIME = 1L; //当线程数大于核心线程数时,多余的空闲线程存活的最长时间
23 
24     public static void main(String... args) {
25         //使用阿里巴巴推荐的创建线程池的方式
26         //通过ThreadPoolExecutor构造函数自定义参数创建
27         ThreadPoolExecutor executor = new ThreadPoolExecutor(
28                 CORE_POOL_SIZE,
29                 MAX_POOL_SIZE,
30                 KEEP_ALIVE_TIME, //当线程数大于核心线程数时,多余的空闲线程存活的最长时间
31                 TimeUnit.SECONDS, //时间单位
32                 new ArrayBlockingQueue<>(QUEUE_CAPACITY), //任务队列,用来储存等待执行任务的队列
33                 new ThreadPoolExecutor.CallerRunsPolicy()); //饱和策略,简单点说就是后面排队的线程就在那儿等着。
34                 //被拒绝的任务在主线程中运行,所以主线程就被阻塞了,别的任务只能在被拒绝的任务执行完之后才会继续被提交到线程池执行
35 
36         for (int i = 0; i < 5; i++) {
37             //创建WorkerThread对象(WorkerThread类实现了Runnable 接口) 每一个Runable都是一个任务
38             //Runnable worker = new MyRunnable("" + i);
39             TicketRunnable ticketRunnable = new TicketRunnable();
40             //执行Runnable
41             executor.execute(ticketRunnable);
42 
43         }
44         //终止线程池
45         // void shutdown() 启动一次顺序关闭,执行以前提交的任务,但不接受新任务。若已经关闭,则调用没有其他作用。
46         executor.shutdown();
47         //boolean isTerminated()
48         //若关闭后所有任务都已完成,则返回true。注意除非首先调用shutdown或shutdownNow,否则isTerminated永不为true。
49         while (!executor.isTerminated()) {
50             //System.out.println("线程池还没有完全关闭!!!");
51         }
52         System.out.println("Finished all threads");
53     }
54 }

 

上一篇:线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor的方式


下一篇:ThreadPool线程池