为了账号安全,请及时绑定邮箱和手机立即绑定

使用 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 关注
  • 148 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信