背景:是這樣的今天在地鐵上瀏覽了以下網頁,看到網上一朋友問了一個多線程的問題。晚上閑着沒事就決定把它實現出來。
題目:
1.開啟兩個線程,一個線程打印A~Z,兩一個線程打印1~52的數據。
2.實現交替打印,輸出結果為12A34B...........5152Z.
3.請用多線程方式實現。
這種只有兩個線程交替打印數據的題目其實相對還是比較簡單的,如果利用傳統線程無非就是synchronized(線程互斥)與wait(),notify()的問題。
今天不用傳統線程解決這個問題,我們用Java 1.5提供的線程並發庫中的類來實現這個功能(實現流程和傳統線程一樣)
下面是實現代碼(我都加了注釋,如果還是不同大家可以查看Java 1.5以上的幫助文檔)
package cn.yw.thread.practice; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** * 多線程練習: * 1.開啟一個線程打印1~52,開啟另一個線程打印A~Z * 打印方式:12A34B46C依次打印 * @author yw-tony * */ public class PracticeTest { public static void main(String[] args){ final DataPrint data = new DataPrint(); //打印字母的線程(大家也可以把這兩個線程抽取出來作為兩個單獨的類,這里為了實現簡單我就直接寫在main方法中了) new Thread(new Runnable(){ @Override public void run() { while(data.letterFlag){ data.printLetter(); } } }).start(); //打印數字的線程 new Thread(new Runnable(){ @Override public void run() { while(data.numFlag){ data.printNun(); } } }).start(); } /** * 打印類 * @author yw-tony * */ static class DataPrint{ public boolean letterFlag = true;//線程結束標記; public boolean numFlag = true; //數字的初始值 int num = 1; //字母的初始值 //這里A~Z的字母對應的阿拉伯數字為65~90, int letter = 65; //線程等待標記 boolean flag = true; //java線程並發庫中的鎖相當與(synchronized) Lock lock = new ReentrantLock(); //線程並發庫中用於線程之間通訊的類相當於wait(),notify() Condition condLetter = lock.newCondition(); Condition condNum = lock.newCondition(); /** * 打印字字母的方法 * */ public void printLetter(){ //如果打印到Z則結束線程並停止 if(letter >= 90 ){ letterFlag = false; return ; } //鎖定代碼塊,鎖定時其他線程不能訪問其中內容 lock.lock(); try{ if(flag){//如果執行打印數字的線程正在執行,則該線程進入等待狀態 condLetter.await(); } System.out.println(Thread.currentThread().getName()+":"+(char)letter); letter++; Thread.sleep(100); //打印執行完成,喚醒打印數字的線程 flag = true; condNum.signal(); }catch(Exception e){ e.printStackTrace(); }finally{ //解鎖當前代碼快 lock.unlock(); } } /** * 打印數字的方法 */ public void printNun(){ //如果打印到52則結束線程並停止 if(num>=52){ numFlag = false; return; } lock.lock(); try{ if(!flag){ condNum.await(); } System.out.println(Thread.currentThread().getName()+":"+num); num++; System.out.println(Thread.currentThread().getName()+":"+num); num++; Thread.sleep(100); flag = false; condLetter.signal();//喚醒打印字母的線程 }catch(Exception e){ e.printStackTrace(); }finally{ lock.unlock(); } } } }