当前位置:编程学习 > JAVA >>

JAVA多线程中synchronized,wait和notify的关系

synchronized是和一个锁对象关联的,synchronized限制static方法的时候,
锁对象为这个类的class变量,相当于XXXClass.class.
synchronized限制非static方法的时候,锁对象为这个类的实例(相当于this).
synchronized限制一个对象实例的时候,如(synchronized (xlock)),锁对象为指定的这个对象实例,如xlock.
只有获得锁对象的锁的线程才能执行synchronized限制的代码.
synchronized限制static方法的时候,在某一时刻,同一个虚拟机只能有一个线程正在执行这个static方法,
因为锁对象是这个class的XXXClass.class实例,一个虚拟机只有一个XXXClass.class实例.
synchronized限制某一个类的非static方法的时候,对这个类的某一特定实例,
在某一时刻,同一个虚拟机只能有一个线程正在执行这个方法,但是可以同时执行多个实例的这个特定方法,因为锁对象不同.
wait,notify和notifyAll都只能在一个锁对象上调用,否则会发生如下异常:
java.lang.IllegalMonitorStateException: current thread not owner
下面的代码是合法的:第一个例子相当于调用了this.notifyAll();this这时候为锁对象.
[java]
public synchronized void sendNotification() throws Exception { 
    notifyAll(); 

 
synchronized (NotifyWaitTest.lock) { 
    try { 
        NotifyWaitTest.lock.notifyAll(); 
    } catch (Exception e) { 
        e.printStackTrace(); 
    } 

public synchronized void sendNotification() throws Exception {
    notifyAll();
}

synchronized (NotifyWaitTest.lock) {
    try {
        NotifyWaitTest.lock.notifyAll();
    } catch (Exception e) {
        e.printStackTrace();
    }
}void notify()
唤醒在此对象监视器上等待的某一个线程.具体是哪一个可以认为是不确定的.
void notifyAll()
唤醒在此对象监视器上等待的所有线程。
void wait()
导致当前的线程等待,直到其他线程调用此对象的 notify()方法或 notifyAll()方法.
wait会释放占有的锁,notify和notifyAll不会释放占用的锁.
下面通过一个实例代码来讲解一下:
[java]
public class NotifyWaitTest { 
    public static Class lock = NotifyWaitTest.class; 
 
    public static void main(String[] args) throws Exception { 
        // new TestThread1().start();  
        // new TestThread1().start();  
        new TestThread2().start(); 
        new TestThread2().start(); 
 
        Thread.sleep(3000);  
        // NotifyWaitTest.lock.notifyAll(); //# poing 1  
        synchronized (NotifyWaitTest.lock) { 
            try { 
                System.out.println(Thread.currentThread().getName() + " sent notification all"); 
                NotifyWaitTest.lock.notifyAll(); 
 
                // System.out.println(Thread.currentThread().getName() + " sent notification 1");  
                // NotifyWaitTest.lock.notify();  
                // System.out.println(Thread.currentThread().getName() + " sent notification 2");  
                // Thread.sleep(3000);  
                // NotifyWaitTest.lock.notify();  
                // System.out.println(Thread.currentThread().getName() + " sent notification over");  
 
            } catch (Exception e) { 
                e.printStackTrace(); 
            } 
        } 
    } 
 

 
class TestThread1 extends Thread { 
    public void run() { 
        synchronized (NotifyWaitTest.lock) { 
            try { 
                System.out.println(Thread.currentThread().getName() + " wait for notification"); 
                NotifyWaitTest.lock.wait(); 
 
                System.out.println(Thread.currentThread().getName() + " wake up"); 
                for (int i = 0; i < 3; i++) { 
                    Thread.sleep(1000); 
                    System.out.println(Thread.currentThread().getName() + " doing " + i); 
                } 
            } catch (Exception e) { 
                e.printStackTrace(); 
            } 
            System.out.println(Thread.currentThread().getName() + " finished"); 
        } 
    } 

 
class TestThread2 extends Thread { 
 
    public void run() { 
        synchronized (NotifyWaitTest.lock) { 
            System.out.println(Thread.currentThread().getName() + " wait for notification"); 
            try { 
                NotifyWaitTest.lock.wait(); 
            } catch (InterruptedException e) { 
                e.printStackTrace(); 
            } 
        } 
   &n

补充:软件开发 , Java ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,