为什么我使用wait()/ notify()对象是什么问题,如果我只是想在线程之间发出信号?

Eri*_* S. 3 java concurrency multithreading wait thread-synchronization

所以我有一个经典案例"我的代码可行,但我不知道为什么".

我有一个创建线程的程序,当我从扫描仪接收到某个输入时,我将字符串的控制权传递给工作线程.为此,我创建了我的线程wait(),当我从UI线程获得正确的输入时,我通知().

这是我的代码.为简单起见,我刚刚使用了一个线程.

package main;

import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;


class ThreadDemo extends Thread {
       private Thread t;
       private String threadName;
       volatile Boolean keepRunning = true;
       private Queue<String> q = new LinkedList<String>();


       ThreadDemo( String name){
           threadName = name;
           System.out.println("Creating " +  threadName );
       }

       public void in(String ex){
           q.add(ex);
           System.out.println("Added " + ex + "to queue of " + threadName);
           synchronized(t){
               t.notify();
           }       
       }


       public void run() {
           System.out.println("Starting to loop.");
            while (keepRunning) {
                try {
                    //Why does it matter that I synchronized t? 
                    synchronized(t){
                        System.out.println(threadName +  "Waiting");
                        t.wait();
                    }
                } catch (InterruptedException e) {
                    System.out.println("Thread interrupted " + e.toString());
                    }
                System.out.println(threadName +  "notified");
                if (q.size()>0){
                    String out = q.remove();
                    System.out.println(threadName + "received " + out);
                }
            }
            System.out.println("Done looping.");
       }

       public void start ()
       {
          System.out.println("Starting " +  threadName );
          if (t == null)
          {
             t = new Thread (this, threadName);
             t.start ();
          }
       }
    }


public class DataAnalysisProgram {

    public static void main(String[] args) {
          ThreadDemo T1 = new ThreadDemo( "Thread-1");
          T1.start();

          System.out.println("say something");
          Scanner s = new Scanner(System.in);
          String t;
          do{
              t = s.next();
              T1.in(t);
          }while (!t.equals("stop"));

          T1.keepRunning = false;
          T1.interrupt();
          s.close();
    }
} 
Run Code Online (Sandbox Code Playgroud)

所以这很好.我的线程一直等到我使用notify.不过,我真的不明白其中的反对我所说的意义notifywait上.

在我的实现中,我不知道如何t.wait()/t.notify(),其中t是我的线程对象.我想如果我这样做,它仍然可以工作threadName.wait()/threadName.notify().为什么我们调用notify并等待看似随意的对象?我知道我在这里错过了关于通知和等待的概念.

Mar*_*nik 6

实际上,当您waitThread实例上调用时,您违反了合同:

建议应用程序无法使用wait,notifynotifyAllThread实例.

这是因为Thread它用于内部目的.

回答你的问题:Thread对象不是一个线程.话说t.notify() 不通知t,它会通知一个线程等待t的监视器.在此上下文中,实例Thread只是另一个Java对象,并且所有Java对象都有一个与之关联的监视器.

您使用监视器的建议String threadName是另一个坏主意,因为您不控制字符串实例的生命周期,并且可能容易践踏实习字符串的问题.

建议不要在线程协调中涉及任意对象的监视器,但更喜欢使用专用的实例Object.这是由于关注点分离原则的一般优点所促成的.