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

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

使用 while 循環強制代碼等待條件需要 thread.sleep()

使用 while 循環強制代碼等待條件需要 thread.sleep()

瀟湘沐 2023-09-27 16:26:34
我創建了一個程序,將線性搜索(搜索 -1)劃分為 4 個單獨的線程。public class main {    static boolean found = false;    public static void main(String[] args) {        // TODO Auto-generated method stub        int threadCount = 4; //amount of threads to use        Random rand = new Random();        Searcher[] s_arr = new Searcher[threadCount]; //array of threads        int[] arr = new int[10000]; //array to search through        for (int i = 0; i < arr.length; i++) //randomizing #'s in array            arr[i] = (int) (rand.nextFloat() * 1000);        int randIndex = rand.nextInt(arr.length); //choose random index        arr[randIndex] = -1; //set random index to = -1        for (int i = 0; i < threadCount; i++) { //            s_arr[i] = new Searcher(Arrays.copyOfRange(arr, i * (arr.length/threadCount), (i+1) * (arr.length/threadCount)),                     (int) (i), i); //assign subarray for this thread to search through            System.out.println(s_arr[i].wait);            s_arr[i].start();         }        //CODE IN QUESTION HERE ----------------------------        //while (!found) ;        while (!found) //wait until value is found        {            try {                Thread.sleep(1);            } catch (InterruptedException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }        }我已經標記出了有問題的代碼,在使用第一個(注釋掉的)while 循環時,程序不會超出該點,但是如果我切換并使用它正下方的另一個 while 循環(強制它的那個循環)每個迭代器等待 1 毫秒)程序運行得很好。為什么會這樣?是否有更有效/實用的方法來完成這項任務?
查看完整描述

1 回答

?
不負相思意

TA貢獻1777條經驗 獲得超10個贊

在空循環語句的條件內重復讀取非易失性字段可能會導致無限循環,因為編譯器優化可能會將此字段訪問移出循環。


來源:help.semmle.com


如果你替換static boolean found = false;為volatile static boolean found = false;,第一個循環將起作用,但我不推薦它,因為它會浪費你的CPU時間。您應該考慮使用wait和notify。


下面static boolean found,添加static final Object lock = new Object();兩個while循環并將其替換為


try {

    synchronized (lock) {

        // we will wait here until we get notified

        lock.wait();

    }

} catch (InterruptedException e) {

    e.printStackTrace();

}

main.found = true添加后也是如此


synchronized (main.lock) {

    main.lock.notify();

}

最后,你的代碼應該是這樣的


public class main {


    static boolean found;

    static final Object lock = new Object();


    public static void main(String[] args) {

        // TODO Auto-generated method stub


        int threadCount = 4; //amount of threads to use

        Random rand = new Random();

        Searcher[] s_arr = new Searcher[threadCount]; //array of threads



        int[] arr = new int[10000]; //array to search through

        for (int i = 0; i < arr.length; i++) //randomizing #'s in array

            arr[i] = (int) (rand.nextFloat() * 1000);


        int randIndex = rand.nextInt(arr.length); //choose random index


        arr[randIndex] = -1; //set random index to = -1


        for (int i = 0; i < threadCount; i++) { //

            s_arr[i] = new Searcher(Arrays.copyOfRange(arr, i * (arr.length/threadCount), (i+1) * (arr.length/threadCount)),

                    (int) (i), i); //assign subarray for this thread to search through

            System.out.println(s_arr[i].wait);

            s_arr[i].start();

        }


        try {

            synchronized (lock) {

                lock.wait();

            }

        } catch (InterruptedException e) {

            e.printStackTrace();

        }


        System.out.println("found!");


        for (int i = 0; i < threadCount; i++) {

            try {

                s_arr[i].join(); //wait for the threads in order before continuing

                System.out.println("Thread ["+i+"] completed");

            } catch (InterruptedException e) {

                // TODO Auto-generated catch block

                e.printStackTrace();

            }

        }

        System.out.println("All threads stopped, program complete.");

    }


}


class Searcher extends Thread {


    int[] arr;

    int wait;

    int index;


    public Searcher(int[] arr, int wait, int i) {

        this.arr = arr;

        this.wait = wait;

        this.index = i;

    }


    @Override

    public void run() {

        for (int i = 0; i < arr.length; i++) {

            if (arr[i] == -1) {

                System.out.println("["+index+"] -1 Found at index: "+i);

                main.found = true;

                synchronized (main.lock) {

                    main.lock.notify();

                }

                break;

            }

            if (main.found) break;

            //purposely slow down this thread

            try {

                Thread.sleep(wait);

            } catch (InterruptedException e) {

                // TODO Auto-generated catch block

                e.printStackTrace();

            }

        }

        System.out.println("["+index+"] has stopped");


    }


}



查看完整回答
反對 回復 2023-09-27
  • 1 回答
  • 0 關注
  • 183 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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