使用 while 循环强制代码等待条件需要 thread.sleep()

我创建了一个程序,将线性搜索(搜索 -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 毫秒)程序运行得很好。


为什么会这样?是否有更有效/实用的方法来完成这项任务?


潇湘沐
浏览 100回答 1
1回答

不负相思意

在空循环语句的条件内重复读取非易失性字段可能会导致无限循环,因为编译器优化可能会将此字段访问移出循环。来源: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 {&nbsp; &nbsp; synchronized (lock) {&nbsp; &nbsp; &nbsp; &nbsp; // we will wait here until we get notified&nbsp; &nbsp; &nbsp; &nbsp; lock.wait();&nbsp; &nbsp; }} catch (InterruptedException e) {&nbsp; &nbsp; e.printStackTrace();}main.found = true添加后也是如此synchronized (main.lock) {&nbsp; &nbsp; main.lock.notify();}最后,你的代码应该是这样的public class main {&nbsp; &nbsp; static boolean found;&nbsp; &nbsp; static final Object lock = new Object();&nbsp; &nbsp; public static void main(String[] args) {&nbsp; &nbsp; &nbsp; &nbsp; // TODO Auto-generated method stub&nbsp; &nbsp; &nbsp; &nbsp; int threadCount = 4; //amount of threads to use&nbsp; &nbsp; &nbsp; &nbsp; Random rand = new Random();&nbsp; &nbsp; &nbsp; &nbsp; Searcher[] s_arr = new Searcher[threadCount]; //array of threads&nbsp; &nbsp; &nbsp; &nbsp; int[] arr = new int[10000]; //array to search through&nbsp; &nbsp; &nbsp; &nbsp; for (int i = 0; i < arr.length; i++) //randomizing #'s in array&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; arr[i] = (int) (rand.nextFloat() * 1000);&nbsp; &nbsp; &nbsp; &nbsp; int randIndex = rand.nextInt(arr.length); //choose random index&nbsp; &nbsp; &nbsp; &nbsp; arr[randIndex] = -1; //set random index to = -1&nbsp; &nbsp; &nbsp; &nbsp; for (int i = 0; i < threadCount; i++) { //&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; s_arr[i] = new Searcher(Arrays.copyOfRange(arr, i * (arr.length/threadCount), (i+1) * (arr.length/threadCount)),&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (int) (i), i); //assign subarray for this thread to search through&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.out.println(s_arr[i].wait);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; s_arr[i].start();&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; try {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; synchronized (lock) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; lock.wait();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; } catch (InterruptedException e) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; e.printStackTrace();&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; System.out.println("found!");&nbsp; &nbsp; &nbsp; &nbsp; for (int i = 0; i < threadCount; i++) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; try {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; s_arr[i].join(); //wait for the threads in order before continuing&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.out.println("Thread ["+i+"] completed");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } catch (InterruptedException e) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // TODO Auto-generated catch block&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; e.printStackTrace();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; System.out.println("All threads stopped, program complete.");&nbsp; &nbsp; }}class Searcher extends Thread {&nbsp; &nbsp; int[] arr;&nbsp; &nbsp; int wait;&nbsp; &nbsp; int index;&nbsp; &nbsp; public Searcher(int[] arr, int wait, int i) {&nbsp; &nbsp; &nbsp; &nbsp; this.arr = arr;&nbsp; &nbsp; &nbsp; &nbsp; this.wait = wait;&nbsp; &nbsp; &nbsp; &nbsp; this.index = i;&nbsp; &nbsp; }&nbsp; &nbsp; @Override&nbsp; &nbsp; public void run() {&nbsp; &nbsp; &nbsp; &nbsp; for (int i = 0; i < arr.length; i++) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (arr[i] == -1) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.out.println("["+index+"] -1 Found at index: "+i);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; main.found = true;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; synchronized (main.lock) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; main.lock.notify();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (main.found) break;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //purposely slow down this thread&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; try {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Thread.sleep(wait);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } catch (InterruptedException e) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // TODO Auto-generated catch block&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; e.printStackTrace();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; System.out.println("["+index+"] has stopped");&nbsp; &nbsp; }}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java