多個線程實現順序打印數據,(可自定義線程一次打印數量和總數量)
阿新 • • 發佈:2017-12-02
技術分享 str logs ges his .get shm import pre
最近看到一道面試題:讓3個線程順序打印數字,如線程1打印1-5,線程2打印6-10,線程3打印11-15,然後是線程1打印16-20...一直打印到75結束。
這到題主要問題有兩點:
第一點是不能讓線程打印的過程中出現其他線程
第二點是要實現線程進入的過程是有序的,如上123123..這樣。
我先是把基本的功能實現了,後來發現可以改造一下,做成可擴展的,即每次打印的數量可自定義,總的數量可自定義,並且保證線程的順序是有序的,下面是具體代碼:
PrintQueue.java 文件,同步線程,控制打印順序,也是最主要的方法
package com.cky;import java.util.LinkedHashMap; import java.util.Map; public class PrintQueue { public int targetNum=0; //要打印的目標數量 public int printOnce=0; //一次要打印的次數 private int nowNum=1; //目前打印到的數量 /** * * @param targetNum 要打印的目標數量 * @param printOnce 一次要打印的次數*/ public PrintQueue(int targetNum, int printOnce) { super(); this.targetNum = targetNum; this.printOnce = printOnce; } private int nextThreadNum=0;//下次要執行線程的下標 private int threadCount=0;//總的線程數量 //map集合,存放線程,鍵是具體線程,值存放線程打印的順序 private Map<Thread,Integer> threads=newLinkedHashMap<Thread,Integer>(); //添加線程 public void setThread(Thread thread) { threads.put(thread, threadCount); threadCount++; } //運行線程 public void run() { for (Thread thread : threads.keySet()) { thread.start(); } } public synchronized void printNum() throws InterruptedException { //獲取當前線程 Thread currentThread=Thread.currentThread(); //獲取當前線程坐標 int currentNum=threads.get(currentThread); //判斷是否為期望線程 if(currentNum==nextThreadNum) { for(int i=0;i<printOnce;i++) { System.out.println("當前線程:"+currentThread.getName()+":"+nowNum++); if(nowNum>targetNum) { System.out.println("工作完成"); this.wait(); } } //期望線程名+1 nextThreadNum=(++nextThreadNum)%threadCount; } } }
RunTest.java 很簡單的Runable接口實現,功能就是請求打印
package com.cky; class RunTest implements Runnable{ PrintQueue ps; public RunTest(PrintQueue ps ) { this.ps=ps; } @Override public void run() { try { while(true) { ps.printNum(); } } catch (InterruptedException e) { e.printStackTrace(); } } }
ThreadDemo.java 測試類
package com.cky; public class ThreadDemo { public static void main(String [] args) { //設置一共打印20個,每個線程一次只打印3個
PrintQueue ps=new PrintQueue(20, 3);
//添加線程 ps.setThread(new Thread(new RunTest(ps),"王大錘")); ps.setThread(new Thread(new RunTest(ps),"張全蛋")); ps.setThread(new Thread(new RunTest(ps),"二狗")); ps.run(); } }
執行結果:
多個線程實現順序打印數據,(可自定義線程一次打印數量和總數量)