Java n個執行緒輪流列印數字的問題
阿新 • • 發佈:2019-01-02
一. 實現兩個執行緒,輪流打印出數字,如下:
bThread --> 10
aThread --> 9
bThread --> 8
aThread --> 7
bThread --> 6
aThread --> 5
bThread --> 4
aThread --> 3
bThread --> 2
aThread --> 1
用java中的Lock類實現:
用synchronized實現:package com.yjq.thread_demo; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class TwoThreadPrinter { private Lock threadLock = new ReentrantLock(); private boolean flag = false; int count =10; Thread aThread = new Thread(new Runnable() { public void run() { while (true) { // 鎖定 threadLock.lock(); try { if ( count < 1) { return; } if (flag) { // aThread的任務 System.out.println("aThread --> " + (count--)); flag = !flag; } } catch (Exception e) { // TODO: handle exception } finally { // 釋放鎖 threadLock.unlock(); } } } }); Thread bThread = new Thread(new Runnable() { public void run() { while (true) { // 鎖定 threadLock.lock(); try { if ( count < 1) { return; } if (!flag) { // aThread的任務 System.out.println("bThread --> " + (count--)); flag = !flag; } } catch (Exception e) { // TODO: handle exception } finally { // 釋放鎖 threadLock.unlock(); } } } }); public void startTwoThread() { aThread.start(); bThread.start(); } public static void main(String[] args) { TwoThreadPrinter twoThreadPrinter = new TwoThreadPrinter(); twoThreadPrinter.startTwoThread(); } }
package com.yjq.thread_demo; public class TwoThreadPrinter2 { private Object threadLock = new Object(); int count =10; Thread aThread = new Thread(new Runnable() { public void run() { while (true) { // 鎖定 synchronized (threadLock) { if ( count < 1) { return; } // // aThread的任務 System.out.println("aThread --> " + (count--)); threadLock.notify(); try { threadLock.wait(); } catch (Exception e) { // TODO: handle exception } } } } }); Thread bThread = new Thread(new Runnable() { public void run() { while (true) { // 鎖定 synchronized (threadLock) { if ( count < 1) { return; } // // aThread的任務 System.out.println("bThread --> " + (count--)); threadLock.notify(); try { threadLock.wait(); } catch (Exception e) { // TODO: handle exception } } } } }); public void startTwoThread() { aThread.start(); bThread.start(); } public static void main(String[] args) { TwoThreadPrinter twoThreadPrinter = new TwoThreadPrinter(); twoThreadPrinter.startTwoThread(); } }
用Lock類的方法比較容易理解, lock() 和 unlock()之間的塊是被鎖定的
用synchronize的方法少用了個flag來標誌輪到哪個執行緒來列印,這是因為執行緒鎖的notifity( )方法會釋放鎖並喚醒其他執行緒 ,執行緒鎖的wait( )方法則是釋放鎖並休眠當前執行緒,如果剛好只有兩個執行緒,那麼自然就是開始另一個執行緒而休眠本執行緒。
二.擴充套件到n個執行緒輪流列印數字的問題
n個執行緒輪流列印數字,用Lock類是比較容易擴充套件的
比如三個執行緒輪流列印數字
package com.myexample.test; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class ThreeThreadPrinter { private Lock threadLock = new ReentrantLock(); private int flag = 0; int count =10; Thread aThread = new Thread(new Runnable() { public void run() { while (true) { // 鎖定 threadLock.lock(); try { if ( count < 1) { return; } if (count%3 == 0 ) { // aThread的任務 System.out.println("aThread --> " + count); count--; } } catch (Exception e) { // TODO: handle exception } finally { // 釋放鎖 threadLock.unlock(); } } } }); Thread bThread = new Thread(new Runnable() { public void run() { while (true) { // 鎖定 threadLock.lock(); try { if ( count < 1) { return; } if (count%3 == 1 ) { // aThread的任務 System.out.println("bThread --> " + count); count--; } } catch (Exception e) { // TODO: handle exception } finally { // 釋放鎖 threadLock.unlock(); } } } }); Thread cThread = new Thread(new Runnable() { public void run() { while (true) { // 鎖定 threadLock.lock(); try { if ( count < 1) { return; } if (count%3 == 2 ) { // aThread的任務 System.out.println("cThread --> " + count); count--; } } catch (Exception e) { // TODO: handle exception } finally { // 釋放鎖 threadLock.unlock(); } } } }); public void startTwoThread() { aThread.start(); bThread.start(); cThread.start(); } public static void main(String[] args) { ThreeThreadPrinter twoThreadPrinter = new ThreeThreadPrinter(); twoThreadPrinter.startTwoThread(); } }
輸出結果
bThread --> 10
aThread --> 9
cThread --> 8
bThread --> 7
aThread --> 6
cThread --> 5
bThread --> 4
aThread --> 3
cThread --> 2
bThread --> 1