首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >多线程状态相关问题

多线程状态相关问题
EN

Stack Overflow用户
提问于 2011-06-28 05:09:01
回答 3查看 505关注 0票数 1

我得到了以下代码片段:

代码语言:javascript
复制
public class ThreadTest{

  private static class Thread01 extends Thread{
    private Thread02 _th2; 
    public int foo = 0;

    public void setThrd02(Thread02 thrd2){
       _th2 = thrd2;
    }

    public void run(){
      try{
        for(int i=0;i<10;i++) foo += i;

        synchronized(this){this.notify();};

        synchronized(_th2){_th2.wait();};

        System.out.print(" Foo: " + _th2.foo);
      }catch(InterruptedException ie){ ie.printStackTrace();}    
    }
  }

  private static class Thread02 extends Thread{

    private final Thread01 _th1;
    public int foo = 0;

    public Thread02(Thread01 th1){
      _th1 = th1;
    }

    public void Run(){
       try{
         synchronized(_th1){_th1.wait();}
         foo = _th1.foo;

         for(int i=0;i<10;i++) foo += i;
         synchronized(this){this.notify();};
           }
       catch(InterruptedException ie){ie.printStackTrace();}

    }

  }

  public static void main(){
    Thread01 th1 = new Thread01();
    Thread02 th2 = new Thread02(th1);

    th1.setThrd02(th2);

    th1.start(); th2.start();
    th1.join(); th2.join();
  } 
}

我认为代码的假设和相应的目的类似于th2先运行,通过调用_th1.wait()将其更改为等待状态;然后,th1计算foo并唤醒th2,th1进入等待状态;Th2从thread1读取foo并更新为110,然后唤醒th1和th2退出。然后退出th1。

线程可能是非常危险的,因为线程1很可能先运行,而线程2将永远等待。

我不确定代码的任何其他潜在问题。

一种可能的解决问题的方法是,例如,在thread1中

公共类ThreadTest{

私有静态布尔更新= false;私有静态布尔完成= false;

私有静态Thread01扩展了线程{

public void Run(){ //执行calcuation (已完成){ wait();} //输出结果}}

私有静态运行扩展了线程{ public void Thread02 (){

while(false){ wait();}

foo = th1.foo;//进行计算//类似机制通知线程1}}

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-06-28 05:23:54

你的线程没有排序的保证。对于Thread01来说,在Thread02执行synchronized(_th1){_th1.wait();}之前通过synchronized(this){this.notify();};就足以让两个线程都无限期地等待。

注意:您在_th1和_th2上调用waitnotify这一事实是无关紧要的。这里的线程将被视为任何其他对象。

票数 4
EN

Stack Overflow用户

发布于 2011-06-28 07:01:33

@Alex已经指出了等待和通知没有按照代码期望的顺序调用(+1)的问题。然而,由于这是一个面试问题,所以这段代码还存在其他几个问题:

  1. 可怕的命名约定和代码格式、
  2. 公共字段访问器、线程对象上的
  3. 同步(奇怪)、
  4. 捕获InterruptedException然后退出线程、

<代码>H19无异常处理、<代码>H210<代码>H111(个人偏好)不使用Java并发库。<代码>H212<代码>G213

我相信这个问题的提出是为了让你感到困惑,并弄清楚为什么并发被破坏了,但是,我想,这些代码是如此丑陋,我甚至不会开始调试它--我只是把它扔掉了。

票数 2
EN

Stack Overflow用户

发布于 2011-06-28 07:05:42

下面是一个更好的修复方法

代码语言:javascript
复制
public class ThreadTest{
  private static volatile boolean updated = false; 
  private static volatile boolean finished = false;


   private static class Thread01 extends Thread{
    private Thread02 _th2; 
    public int foo = 0;

    public void setThread2(Thread02 th2){
        _th2 = th2;
    }

    public void Run(){          

        for(int i=0;i<10;i++) foo += i;
        System.out.print(" thread1 calcualtion " + foo + "\n");

        try{
        updated = true; 
        synchronized(this) {this.notify();};

        synchronized(_th2){
             while(!finished) 
                 _th2.wait();
             System.out.print("Foo: " + _th2.foo );    
          } 
    } 
    catch(InterruptedException ie){
        ie.printStackTrace();
    }
}
 }

  private static class Thread02 extends Thread{ 
    private final Thread01 _th1;
    public int foo = 0;

    public Thread02(Thread01 th1){
        _th1 = th1;
    }
    public void run(){
    try{
        synchronized(_th1){
            while(!updated) 
                _th1.wait();
        foo = _th1.foo; 
        } 
    for(int i=0;i<10;i++) foo +=i; 
    finished = true; 
    synchronized(this){ this.notify();}
    }catch(InterruptedException ie){
        ie.printStackTrace();
    }
}
 }

public static void main(String[] args) {
    // TODO Auto-generated method stub
    Thread01 th1 = new Thread01();
    Thread02 th2 = new Thread02(th1);

    th1.setThread2(th2);

    try{
    th1.start();
    th2.start();
    th1.join();
    th2.join();
    }catch(InterruptedException ie){
        ie.printStackTrace();
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6498982

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档