亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

FairSync能否保證執行順序?

FairSync能否保證執行順序?

翻閱古今 2023-07-19 15:48:33
我的第一個問題,謝謝您的幫助!我正在嘗試使用兩個線程交替打印奇數和偶數 1~100。預期成績:    pool-1-thread-1=> 1    pool-1-thread-2=> 2    pool-1-thread-1=> 3    pool-1-thread-2=> 4    ......    pool-1-thread-1=> 99    pool-1-thread-2=> 100我想我可以使用FairSync,但它只能保證大部分打印是正確的。像這樣:pool-1-thread-1=> 55pool-1-thread-2=> 56pool-1-thread-1=> 57pool-1-thread-2=> 58   pool-1-thread-2=> 59  //※error print※pool-1-thread-1=> 60pool-1-thread-2=> 61pool-1-thread-1=> 62不知道為什么極少數情況下訂單會丟失?你可以批評我的代碼和我的英語。這是我的代碼:private static final int COUNT = 100;private static final int THREAD_COUNT = 2;private static int curr = 1;static ReentrantLock lock = new ReentrantLock(true);static ExecutorService executorService = Executors.newCachedThreadPool();public static void main(String[] args) {    Runnable task = () -> {        for (; ; ) {            try {                lock.lock();                if (curr <= COUNT) {                    System.out.println(Thread.currentThread().getName() + "=> " + curr++);                } else {                    System.exit(0);                }            } catch (Exception e) {                e.printStackTrace();            } finally {                lock.unlock();            }        }    };    for (int i = 0; i < THREAD_COUNT; i++) {        executorService.execute(task);    }}
查看完整描述

2 回答

?
蝴蝶刀刀

TA貢獻1801條經驗 獲得超8個贊

不,親愛的,你的實施不正確。哪個線程有機會運行是由操作系統決定的。無法保證線程 1 和 2 會相繼執行。


您可以通過檢查變量 curr 的先前值來修復代碼,如果該值不是該線程期望的值,則不要增加并打印。


為我:


if(curr.threadName.equals("Thread 2") && (curr%2 !=0))

{

// Print

// Increment

}


查看完整回答
反對 回復 2023-07-19
?
千萬里不及你

TA貢獻1784條經驗 獲得超9個贊

您不能使用單鎖來實現此目的。即使ReentrantLock提供公平性,但它無法控制線程調度。


我們可以實現像拋出一樣的線程間通信Semaphore。信號量控制線程的執行。


我們創建兩個線程,一個奇數線程和一個偶數線程。奇數線程將打印從 1 開始的奇數,偶數線程將打印從 2 開始的偶數。


創建兩個信號量 semOdd 和 semEven,它們一開始有 1 和 0 許可。這將確保首先打印奇數。


class SharedPrinter {


? ? private Semaphore semEven = new Semaphore(0);

? ? private Semaphore semOdd = new Semaphore(1);


? ? void printEvenNum(int num) {

? ? ? ? try {

? ? ? ? ? ? semEven.acquire();

? ? ? ? } catch (InterruptedException e) {

? ? ? ? ? ? Thread.currentThread().interrupt();

? ? ? ? }

? ? ? ? System.out.println(Thread.currentThread().getName() + num);

? ? ? ? semOdd.release();

? ? }


? ? void printOddNum(int num) {

? ? ? ? try {

? ? ? ? ? ? semOdd.acquire();

? ? ? ? } catch (InterruptedException e) {

? ? ? ? ? ? Thread.currentThread().interrupt();

? ? ? ? }

? ? ? ? System.out.println(Thread.currentThread().getName() + num);

? ? ? ? semEven.release();


? ? }

}


class Even implements Runnable {

? ? private SharedPrinter sp;

? ? private int max;


? ? // standard constructor


? ? @Override

? ? public void run() {

? ? ? ? for (int i = 2; i <= max; i = i + 2) {

? ? ? ? ? ? sp.printEvenNum(i);

? ? ? ? }

? ? }

}


class Odd implements Runnable {

? ? private SharedPrinter sp;

? ? private int max;


? ? // standard constructors?

? ? @Override

? ? public void run() {

? ? ? ? for (int i = 1; i <= max; i = i + 2) {

? ? ? ? ? ? sp.printOddNum(i);

? ? ? ? }

? ? }

}


public static void main(String[] args) {

? ? SharedPrinter sp = new SharedPrinter();

? ? Thread odd = new Thread(new Odd(sp, 10),"Odd");

? ? Thread even = new Thread(new Even(sp, 10),"Even");

? ? odd.start();

? ? even.start();

}


查看完整回答
反對 回復 2023-07-19
  • 2 回答
  • 0 關注
  • 152 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號