0

这段代码将如何工作:

boolean flag=true;
while(flag){
    wait();
    flag=!flag;
}

flag = !flag 会被执行吗?此外,如果将 flag 设置为静态变量(它在实例之间共享)并启动包含以下代码的两个线程:

for(int i=0;i<5;i++){
 flag=!flag;   
 while(flag){
        System.out.println("*");
        wait();
    } 
    notify();
}

为什么程序在打印随机数量的'*'后停止?(即使在使用同步之后)。请解释 while 循环中 wait() 的行为。

4

3 回答 3

1

flag = !flag 会被执行吗?

是的。如果另一个线程调用notify()notifyAll()在这个对象上,wait()调用返回并被flag清除,从而导致循环退出。

为什么程序在打印随机数量的'*'后停止?

如果代码确实如描述的那样,则只*应打印两个,因为线程在调用notify()时无法调用wait(),并且没有显示其他线程正在调用notify()

请用简短、独立、正确的示例替换假代码。

于 2013-11-08T17:36:56.697 回答
1

.wait() 说“我的时间片已经完成了。在有人调用 notify() 之前不要再给我一个时间片。” 除非有人调用 notify()(或发生其他几种唤醒场景之一),否则操作系统甚至不会尝试安排您的任务。

flag = !flag 会被执行吗?

是的,在线程被唤醒之后。

此外,如果将 flag 设置为静态变量并启动两个包含以下代码的线程:

标志是静态的意味着它在实例之间共享,对吗?

假设标志开始为真。

  • 您生成一个线程 A。
  • 您生成另一个线程 B。线程在随机延迟后开始运行。
  • A 将标志从假设置为真。A 开始运行循环。A 等到它再次醒来。
  • 在某个点 B 开始运行。当它这样做时,它将标志设置为假。B 直接去 notify(); 它唯一通知的是它自己。
  • A继续等待notify(),B已经终止。
  • 如果在某个时候通知 A,它将继续循环,看到标志不再为真,然后继续并终止。
于 2013-11-08T17:08:08.417 回答
0

这是一个完整的实现:

class Test implements Runnable{
    static boolean flag=false;
    public static void main(String[] args){
        new Thread(this,"thread1").start();
        new Thread(this,"thread2").start();
    }
    public void run(){
        for(int i=0;i<5;i++){
            flag=!flag;
             try{
                while(flag){
                System.out.println("*");
                wait();
                }
            }catch(InterruptedException e){
                System.out.println("thread interrupted");
            }
            notify();
        }
    }
}

用 if(flag) 语句替换 while(flag) 语句时效果很好。使用 while 时,它​​会在给出完整输出的一部分后停止。

于 2013-11-08T17:56:32.937 回答