使用線程池實現賣票


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 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM