如何通过Java通知特定的线程

Mun*_*y V 4 java multithreading ipc java-threads

如何在线程间通信中调用特定线程?

在下面的程序中,我有两个线程t1t2.

当我称之为t1.notify()加薪:

Exception in thread "Thread-1" java.lang.IllegalMonitorStateException
    at java.lang.Object.notify(Native Method)
    at Shared.methodTwo(NotifyThread.java:43)
    at Thread2.run(NotifyThread.java:77)
Error 
Run Code Online (Sandbox Code Playgroud)
class Shared {

    Thread1 t1 ;
    Thread2 t2 ;

    void ThreadInit( Thread1 t1 , Thread2 t2 ) {
        this.t1 = t1 ;
        this.t2 = t2 ;
    }

    synchronized void methodOne()
    {
        Thread t = Thread.currentThread();

        System.out.println(t.getName()+" is relasing the lock and going to wait");

        try
        {
            wait();        //releases the lock of this object and waits
        }
        catch (InterruptedException e)
        {
            e.printStackTrace();
        }

        System.out.println(t.getName()+" got the object lock back and can continue with it's execution");
    }

    synchronized void methodTwo()
    {
        Thread t = Thread.currentThread();

        try
        {
            Thread.sleep(5000);
        }
        catch (InterruptedException e)
        {
            e.printStackTrace();
        }

        t1.notify();     

        System.out.println("A thread which is waiting for lock of this object is notified by "+t.getName());
    }
    }

    class Thread1 extends Thread 
    {
    Shared s ;
    Thread1( Shared s ) {

        this.s = s ;
    }

    public void run()
            {
                s.methodOne();   //t1 calling methodOne() of 's' object
            }

    } 

    class Thread2 extends Thread {
         Shared s ;
    Thread2( Shared s ) {

        this.s = s ;

    }

    public void run()
            {
                s.methodTwo();   //t1 calling methodOne() of 's' object
            }


    }
    public class NotifyThread 
    {
    public static void main(String[] args)
    {
        final Shared s = new Shared();

        Thread1 t1 = new Thread1(s) ;
        Thread2 t2 = new Thread2(s) ;

        s.ThreadInit(t1,t2) ;

        t1.start();
        t2.start();
    }
}
Run Code Online (Sandbox Code Playgroud)

Ste*_*n C 5

您没有/不能通知特定的线程.你调用notify()一个锁定对象.这会唤醒等待锁定的其中一个线程1.在您的情况下,锁定对象是Thread... ...相当混淆图片.但是,见下文.

但是你的问题(IllegalMonitorStateException)发生是因为执行通知的线程(即当前线程)没有持有锁.(硬)要求当前线程在通知锁时必须保持锁定.

有关更多详细信息,请阅读javadocs Object.wait(timeout)或(例如):http://howtodoinjava.com/core-java/multi-threading/how-to-work-with-wait-notify-and-notifyall-in-java /

1 - 如果多个线程正在等待锁定,则调度程序会"随机"选择一个线程.或者,notifyAll将唤醒所有等待的线程.


我不会将Thread对象用作锁定对象.它可能会工作,但也有可能其他东西(可能是运行时系统中的某些东西)也锁定/等待/通知Thread对象.然后事情会变得非常混乱.

(事实上,阅读的javadocThread.join(long)!)

专门为此目的创建锁定对象更好; 例如

private final Object lock = new Object();
Run Code Online (Sandbox Code Playgroud)

另外,编写扩展的类Thread通常是个坏主意.通常最好实现Runnable接口,实例化它,并将实例作为参数传递给Thread构造函数; 例如

Thread t = new Thread(new Runnable() {
    public void run() {
        System.out.println("Hello world");
    }});
t.start();
Run Code Online (Sandbox Code Playgroud)

实现Runnable而不是扩展的一个优点Thread是,您可以更轻松地使用代码来管理线程生命周期; 例如ExecutorService,一个fork-join线程池或一个经典的线程池.

第二个是轻量级线程逻辑可以简洁地实现为匿名类......就像在我的例子中一样.