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

Java 使用while循环强制代码等待条件需要thread.sleep(),java,multithreading,Java,Multithreading,我创建了一个程序,它将线性搜索-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 =

我创建了一个程序,它将线性搜索-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();
            }
        }
//-----------------------------------------------------------





        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.");
    }

}

public 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;
                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");

    }

}
我已经标记出了有问题的代码,当使用第一个注释掉的while循环时,程序不会超出该点,但是如果我切换并使用它正下方的另一个while循环,强制它在每个迭代器上等待1毫秒,程序就可以正常工作

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

在空循环语句的条件下重复读取非易失性字段可能会导致无限循环,因为编译器优化可能会将此字段访问移出循环

来源:help.semmle.com

如果替换静态布尔值,则find=false;发现易失性静态布尔值=false;,第一个循环可以工作,但我不推荐它,因为它会浪费您的CPU时间。 应该考虑使用等待和通知。

在找到的静态布尔值下面,添加静态最终对象锁=新对象;并将两个while循环替换为

试一试{ 同步锁{ //我们将在这里等待,直到得到通知 锁,等等; } }捕捉中断异常e{ e、 打印跟踪; } 也在main.found=true之后添加

同步主锁{ main.lock.notify; } 最后,您的代码应该如下所示

公共班机{ 发现静态布尔值; 静态最终对象锁定=新对象; 公共静态无效字符串[]args{ //TODO自动生成的方法存根 int threadCount=4;//要使用的线程数量 随机兰德=新的随机; Searcher[]s_arr=newsearcher[threadCount];//线程数组 int[]arr=new int[10000];//要搜索的数组 对于int i=0;i 来源:help.semmle.com

如果替换静态布尔值,则find=false;发现易失性静态布尔值=false;,第一个循环可以工作,但我不推荐它,因为它会浪费您的CPU时间。 应该考虑使用等待和通知。

在找到的静态布尔值下面,添加静态最终对象锁=新对象;并将两个while循环替换为

试一试{ 同步锁{ //我们将在这里等待,直到得到通知 锁,等等; } }捕捉中断异常e{ e、 打印跟踪; } 也在main.found=true之后添加

同步主锁{ main.lock.notify; } 最后,您的代码应该如下所示

公共班机{ 发现静态布尔值; 静态最终对象锁定=新对象; 公共静态无效字符串[]args{ //TODO自动生成的方法存根 内螺纹 adCount=4//要使用的线程数 随机兰德=新的随机; 搜索者[]s_arr=新搜索者[threadCount]//线程数组 int[]arr=新int[10000]//要搜索的数组 对于int i=0;i