Java线程忙着等待

Java线程忙着等待,java,multithreading,busy-waiting,Java,Multithreading,Busy Waiting,嗨,我正在做一个项目,我已经达到了我非常卡住的部分。我试图寻找一些方法来学习如何为繁忙的等待编写while循环,但我没有找到任何东西,我的代码只是作为一个无限循环运行。有人能帮我解释一下繁忙的等待循环应该如何工作,并帮助我打破这个无限循环吗 该项目希望发生以下事情:早上,学生醒来后(这将需要一段随机时间),他将去洗手间为新的一天做准备。如果浴室已经被占用,学生会休息一下(使用yield()),然后他会等待(使用busy waiting)浴室可用。学生将以先到先得的方式使用浴室(您可以使用布尔数组

嗨,我正在做一个项目,我已经达到了我非常卡住的部分。我试图寻找一些方法来学习如何为繁忙的等待编写while循环,但我没有找到任何东西,我的代码只是作为一个无限循环运行。有人能帮我解释一下繁忙的等待循环应该如何工作,并帮助我打破这个无限循环吗

该项目希望发生以下事情:早上,学生醒来后(这将需要一段随机时间),他将去洗手间为新的一天做准备。如果浴室已经被占用,学生会休息一下(使用yield()),然后他会等待(使用busy waiting)浴室可用。学生将以先到先得的方式使用浴室(您可以使用布尔数组/向量来按顺序释放它们)

公共类学生实现可运行
{
private Random rn=新的Random();
私有字符串threadNum;
private volatile boolean bathroomFull=假;
私有静态长时间=System.currentTimeMillis();
私有线程t;
公立学生(字符串学生ID)
{
threadNum=studentID;
t=新线程(此“学生线程”#“+threadNum);
System.out.println(“thread created=“+t”);
//这将调用run()函数
t、 start();
}
公开募捐
{
int waitTime=rn.nextInt(4000-2000+1)+2000;
System.out.println(“当前时间为“+(System.currentTimeMillis()-time)+”,等待时间为“+waitTime”);
//学生在随机时间后醒来
while((System.currentTimeMillis()-time)
这是我的主要方法,它允许用户指定他们想要多少学生线程。是的,我不知道如何实现值的更改,以便中断繁忙的wait-while循环

 public static void main(String args[]) 
   {
       int numberOfStudents;
       numberOfStudents = Integer.parseInt(JOptionPane.showInputDialog("How many students are there in the university? "));
      // System.out.println("there are " + numberOfStudents);

       for(int i = 0; i < numberOfStudents; i++)
       {   
           new Student(String.valueOf(i+1));
       }
          new Teacher();
   }
publicstaticvoidmain(字符串参数[])
{
国际学生人数;
numberOfStudents=Integer.parseInt(JOptionPane.showInputDialog(“大学里有多少学生?”);
//System.out.println(“有”+numberofstudent);
for(int i=0;i
这里是一个繁忙等待的工作示例。它使用原子布尔值指示浴室是否有人占用。原子操作在一个步骤中执行,这对于保证线程安全很重要。我们也可以使用普通布尔值并自己编写
比较数据集

private static synchronized boolean compareAndSet(boolean expected, boolean value) {
    if (occupied == expected) { // (1)
        occupied = value; // (2)
        return true;
    } else {
        return false;
    }
}
这是Java实现的等价物(在本例中)。
synchronized
是必需的,否则在执行
(2)
之前,两个线程有可能在
(1)
处通过测试(因为这两个操作不是原子的),然后两个人一起上厕所

import java.util.concurrent.atomic.AtomicBoolean;

public class Student extends Thread {

    // note the static: there is only one bathroom for all students
    private static AtomicBoolean occupied = new AtomicBoolean(false);

    private String name;

    public Student(String name) {
        this.name = name;
    }

    private void sleep(int millis) {
        try {
            Thread.sleep(millis);
        } catch (InterruptedException e) {
            System.out.println(name + " wet his/her pants");
        }
    }

    @Override
    public void run() {
        int r = (int)(Math.random() * 5000);
        System.out.println(name + " sleeps for " + r + " ms");
        sleep(r);
        System.out.println(name + " goes to bathroom");
        // ***** busy wait *****
        while (!occupied.compareAndSet(false, true)) {
            System.out.println(name + " takes a break");
            Thread.yield();
            sleep(1000);
        }
        // ***** end (in bathroom) *****
        System.out.println(name + " is in the bathroom");
        sleep(1000);
        occupied.set(false);
        System.out.println(name + " goes to university");
    }

    public static void main(String[] args) {
        new Student("Bob").start();
        new Student("Alice").start();
        new Student("Peter").start();
        new Student("Marcia").start();
        new Student("Desmond").start();
        new Student("Sophia").start();
    }

}
可能的产出:

鲍勃睡了2128毫秒
玛西娅睡了3357毫秒
爱丽丝睡了1289毫秒
彼得睡了820毫秒
德斯蒙德睡了1878毫秒
索菲亚睡了2274毫秒
彼得上厕所
彼得在浴室里
爱丽丝去洗手间
爱丽丝休息一下
彼得上大学了
德斯蒙德去洗手间
德斯蒙德在浴室里
鲍勃去洗手间
鲍勃休息一下
索菲亚去洗手间
索菲亚休息一下
爱丽丝休息一下
德斯蒙德上大学
鲍勃在浴室里
索菲亚休息一下
爱丽丝休息一下
玛西娅去洗手间
玛西娅休息一下
鲍勃上大学了
索菲亚在浴室里
爱丽丝休息一下
玛西娅休息一下
索菲亚上大学了
爱丽丝在浴室里
玛西娅休息一下
爱丽丝上大学了
玛西娅在浴室里

Marcia上大学

哪个循环是无限的,哪个值不会改变,哪个值会结束循环。AFAICS
bathroomFull
总是错误的。你的Runnable应该做的就是打印
当前时间是…
,几秒钟后退出。你还想做什么吗?他的循环怎么办?你花了多少钱ct会发生吗?@pathfinderelite我怀疑它正在等待有人更改代码,以便
bathroomFull=true
某个地方。;)请不要在注释中发布代码,因为它丢失了格式,无法阅读。相反,请在之前将任何新代码发布到原始问题的底部。谢谢,您的while循环比我的和我的要好得多谢谢你提供的关于原子布尔的信息,我以前从未听说过。我将只使用向量,因为教授建议使用向量。
import java.util.concurrent.atomic.AtomicBoolean;

public class Student extends Thread {

    // note the static: there is only one bathroom for all students
    private static AtomicBoolean occupied = new AtomicBoolean(false);

    private String name;

    public Student(String name) {
        this.name = name;
    }

    private void sleep(int millis) {
        try {
            Thread.sleep(millis);
        } catch (InterruptedException e) {
            System.out.println(name + " wet his/her pants");
        }
    }

    @Override
    public void run() {
        int r = (int)(Math.random() * 5000);
        System.out.println(name + " sleeps for " + r + " ms");
        sleep(r);
        System.out.println(name + " goes to bathroom");
        // ***** busy wait *****
        while (!occupied.compareAndSet(false, true)) {
            System.out.println(name + " takes a break");
            Thread.yield();
            sleep(1000);
        }
        // ***** end (in bathroom) *****
        System.out.println(name + " is in the bathroom");
        sleep(1000);
        occupied.set(false);
        System.out.println(name + " goes to university");
    }

    public static void main(String[] args) {
        new Student("Bob").start();
        new Student("Alice").start();
        new Student("Peter").start();
        new Student("Marcia").start();
        new Student("Desmond").start();
        new Student("Sophia").start();
    }

}