在下面标记1的地方  调用wait 释放了getJudge(this)资源    但我还想同时释放标记2处的lock锁(lock是个字符串)   我该怎么做?
谢谢public void judgeMethod() {
while (true) {
synchronized (lock) {  //标记2
if (num >= 6) {
System.out.println("   add要停了   reduce开始干活了   ");
synchronized (getAdd(this)) {
try {
getAdd(this).wait();
System.out.println("------ important -----");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized (getReduce(this)) {
getReduce(this).notify();
}
} else if (num <= 3) {
System.out.println("  reduce要停了 add开始干活了  ");
synchronized (getReduce(this)) {
try {
getReduce(this).wait();
} catch (InterruptedException e) {
e.printStackTrace();
} }
synchronized (getAdd(this)) {
getAdd(this).notify();
}
} else {
synchronized (getJudge(this)) {
try {
System.out.println("  大家注意了judge要防锁了  ");
getJudge(this).wait();  // 标记1
} catch (InterruptedException e) {
e.printStackTrace();
} } }
}
}
}

解决方案 »

  1.   

    lz怎么确认lock锁没释放
    wait之后不该是都释放了的吗?
      

  2.   

    lock.notifyAll();> wait之后不该是都释放了的吗?
    锁是不一样滴~~~貌似很乱~~~~~~
      

  3.   

    synchronized块范围
    synchronized (lock) {  //标记2
                if (num >= 6) {
                        System.out.println("   add要停了   reduce开始干活了   ");
                        synchronized (getAdd(this)) {
                            try {
                                getAdd(this).wait();
                                System.out.println("------ important -----");
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                        synchronized (getReduce(this)) {
                            getReduce(this).notify();
                        }
                    } else if (num <= 3) {
                        System.out.println("  reduce要停了 add开始干活了  ");
                        synchronized (getReduce(this)) {
                            try {
                                getReduce(this).wait();
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }                    }
                        synchronized (getAdd(this)) {
                            getAdd(this).notify();
                        }
                    } else {
                        synchronized (getJudge(this)) {
                            try {
                                System.out.println("  大家注意了judge要防锁了  ");
                                getJudge(this).wait();  // 标记1
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }                    }                }
                } //synchronized  lock  结束调用  getJudge(this).wait();  // 标记1     会释放Lock锁??   我觉得只是释放getJudge(this)
      

  4.   

    觉得的根据是什么?
    我试验了一下 貌似是都释放了的class MyThread extends Thread{
        String lock1 = "";
        String lock2 = "";
        
        public void run(){
            System.out.println(Thread.currentThread().getName() + " run");
            
            synchronized (lock1) {
                System.out.println(Thread.currentThread().getName());
                synchronized (lock2) {
                    try {
                        System.out.println("before lock2");
                        MyThread thread2 = new MyThread();
                        thread2.setName("thread2");
                        thread2.start();
                        
                        lock2.wait();
                        System.out.println("after lock2");
                        
                        System.out.println("thread2 started");
                    }
                    catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        }
    }启动
    MyThread thread1 = new MyThread();
    thread1.setName("thread1");
    thread1.start();
      

  5.   

    呃~~~仔细看了下代码(考到eclipse里format了一下)同意dracularking 的说法,是会释放的。因为执行完sleep之后会离开同步区(两个都离开了)。貌似刚才我是这么看的
     synchronized (lock) {  //标记2
                while (num >= 6) {
     ...
    串行了。。
      

  6.   

     dracularking 
    class MyThread extends Thread{
        String lock1 = "";
        String lock2 = "";
        
        public void run(){
            System.out.println(Thread.currentThread().getName() + " run");
            
            synchronized (lock1) { //标记1
                System.out.println(Thread.currentThread().getName());
                synchronized (lock2) {//标记2
                    try {
                        System.out.println("before lock2");
                        MyThread thread2 = new MyThread();
                        thread2.setName("thread2"); //标记3
                        thread2.start();
                        
                        lock2.wait();
                        System.out.println("after lock2");
                        
                        System.out.println("thread2 started");
                    }
                    catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    MyThread thread1 = new MyThread();
    thread1.setName("thread1"); //标记
    thread1.start();dracularking 哥们    这段code会有N个MyThread 对象   每一个MyThread 对象都有一个lock1  lock2   也就是说在run方法中的lock1 lock2 加synchronized  是没有用的   lock2.wait(); 是释放lock2   在这段code中 lock2.wait(); 释不释放lock1   下一个thread还是能进入自己的run方法  和synchronized (lock1)块   因为他有自己的lock1
      

  7.   

     dracularking 
    class MyThread extends Thread{
        String lock1 = "";
        String lock2 = "";
        
        public void run(){
            System.out.println(Thread.currentThread().getName() + " run");
            
            synchronized (lock1) { //标记1
                System.out.println(Thread.currentThread().getName());
                synchronized (lock2) {//标记2
                    try {
                        System.out.println("before lock2");
                        MyThread thread2 = new MyThread();
                        thread2.setName("thread2"); //标记3
                        thread2.start();
                        
                        lock2.wait();
                        System.out.println("after lock2");
                        
                        System.out.println("thread2 started");
                    }
                    catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    MyThread thread1 = new MyThread();
    thread1.setName("thread1"); //标记
    thread1.start();dracularking 哥们    这段code会有N个MyThread 对象   每一个MyThread 对象都有一个lock1  lock2   也就是说在run方法中的lock1 lock2 加synchronized  是没有用的   lock2.wait(); 是释放lock2   在这段code中 lock2.wait(); 释不释放lock1   下一个thread还是能进入自己的run方法  和synchronized (lock1)块   因为他有自己的lock1
      

  8.   

     dracularking
     
    class MyThread extends Thread{
        String lock1 = "";
        String lock2 = "";
        
        public void run(){
            System.out.println(Thread.currentThread().getName() + " run");
            
            synchronized (lock1) { //标记1
                System.out.println(Thread.currentThread().getName());
                synchronized (lock2) {//标记2
                    try {
                        System.out.println("before lock2");
                        MyThread thread2 = new MyThread();
                        thread2.setName("thread2"); //标记3
                        thread2.start();
                        
                        lock2.wait();
                        System.out.println("after lock2");
                        
                        System.out.println("thread2 started");
                    }
                    catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    MyThread thread1 = new MyThread();
    thread1.setName("thread1"); //标记
    thread1.start();dracularking 哥们    这段code会有N个MyThread 对象   每一个MyThread 对象都有一个lock1  lock2   也就是说在run方法中的lock1 lock2 加synchronized  是没有用的   lock2.wait(); 是释放lock2   在这段code中 lock2.wait(); 释不释放lock1   下一个thread还是能进入自己的run方法  和synchronized (lock1)块   因为他有自己的lock1
      

  9.   


     
    class MyThread extends Thread{
        String lock1 = "";
        String lock2 = "";
        
        public void run(){
            System.out.println(Thread.currentThread().getName() + " run");
            
            synchronized (lock1) { //标记1
                System.out.println(Thread.currentThread().getName());
                synchronized (lock2) {//标记2
                    try {
                        System.out.println("before lock2");
                        MyThread thread2 = new MyThread();
                        thread2.setName("thread2"); //标记3
                        thread2.start();
                        
                        lock2.wait();
                        System.out.println("after lock2");
                        
                        System.out.println("thread2 started");
                    }
                    catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    MyThread thread1 = new MyThread();
    thread1.setName("thread1"); //标记
    thread1.start();
    dracularking 哥们    这段code会有N个MyThread 对象   每一个MyThread 对象都有一个lock1  lock2   也就是说在run方法中的lock1 lock2 加synchronized  是没有用的   lock2.wait(); 是释放lock2   在这段code中 lock2.wait(); 释不释放lock1   下一个thread还是能进入自己的run方法  和synchronized (lock1)块   因为他有自己的lock1
      

  10.   

     dracularking 
    class MyThread extends Thread{
        String lock1 = "";
        String lock2 = "";
        
        public void run(){
            System.out.println(Thread.currentThread().getName() + " run");
            
            synchronized (lock1) { //标记1
                System.out.println(Thread.currentThread().getName());
                synchronized (lock2) {//标记2
                    try {
                        System.out.println("before lock2");
                        MyThread thread2 = new MyThread();
                        thread2.setName("thread2"); //标记3
                        thread2.start();
                        
                        lock2.wait();
                        System.out.println("after lock2");
                        
                        System.out.println("thread2 started");
                    }
                    catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    MyThread thread1 = new MyThread();
    thread1.setName("thread1"); //标记
    thread1.start();dracularking 哥们    这段code会有N个MyThread 对象   每一个MyThread 对象都有一个lock1  lock2   也就是说在run方法中的lock1 lock2 加synchronized  是没有用的   lock2.wait(); 是释放lock2   在这段code中 lock2.wait(); 释不释放lock1   下一个thread还是能进入自己的run方法  和synchronized (lock1)块   因为他有自己的lock1
      

  11.   


    class MyThread extends Thread{
        String lock1 = "";
        String lock2 = "";
        
        public void run(){
            System.out.println(Thread.currentThread().getName() + " run");
            
            synchronized (lock1) { 
                System.out.println(Thread.currentThread().getName());
                synchronized (lock2) {
                    try {
                        System.out.println("before lock2");
                        MyThread thread2 = new MyThread();
                        thread2.setName("thread2"); 
                        thread2.start();
                        
                        lock2.wait();
                        System.out.println("after lock2");
                        
                        System.out.println("thread2 started");
                    }
                    catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    MyThread thread1 = new MyThread();
    thread1.setName("thread1"); 
    thread1.start();dracularking 哥们    这段code会有N个MyThread 对象   每一个MyThread 对象都有一个lock1  lock2   也就是说在run方法中的lock1 lock2 加synchronized  是没有用的   lock2.wait(); 是释放lock2   在这段code中 lock2.wait(); 释不释放lock1   下一个thread还是能进入自己的run方法  和synchronized (lock1)块   因为他有自己的lock1
      

  12.   


    class MyThread extends Thread{
        String lock1 = "";
        String lock2 = "";
        
        public void run(){
            System.out.println(Thread.currentThread().getName() + " run");
            
            synchronized (lock1) { 
                System.out.println(Thread.currentThread().getName());
                synchronized (lock2) {
                    try {
                        System.out.println("before lock2");
                        MyThread thread2 = new MyThread();
                        thread2.setName("thread2"); 
                        thread2.start();
                        
                        lock2.wait();
                        System.out.println("after lock2");
                        
                        System.out.println("thread2 started");
                    }
                    catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    MyThread thread1 = new MyThread();
    thread1.setName("thread1"); 
    thread1.start();dracularking 哥们,这段code会有N个MyThread 对象,每一个MyThread 对象都有一个lock1  lock2   也就是说在run方法中的lock1 lock2 加synchronized  是没有用的   lock2.wait(); 是释放lock2   在这段code中 lock2.wait(); 释不释放lock1   下一个thread还是能进入自己的run方法  和synchronized (lock1)块   因为他有自己的lock1
      

  13.   

     dracularking 
    class MyThread extends Thread{
        String lock1 = "";
        String lock2 = "";
        
        public void run(){
            System.out.println(Thread.currentThread().getName() + " run");
            
            synchronized (lock1) { //标记1
                System.out.println(Thread.currentThread().getName());
                synchronized (lock2) {//标记2
                    try {
                        System.out.println("before lock2");
                        MyThread thread2 = new MyThread();
                        thread2.setName("thread2"); //标记3
                        thread2.start();
                        
                        lock2.wait();
                        System.out.println("after lock2");
                        
                        System.out.println("thread2 started");
                    }
                    catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    MyThread thread1 = new MyThread();
    thread1.setName("thread1"); //标记
    thread1.start();dracularking 哥们    这段code会有N个MyThread 对象   每一个MyThread 对象都有一个lock1  lock2   也就是说在run方法中的lock1 lock2 加synchronized  是没有用的   lock2.wait(); 是释放lock2   在这段code中 lock2.wait(); 释不释放lock1   下一个thread还是能进入自己的run方法  和synchronized (lock1)块   因为他有自己的lock1
      

  14.   

    dracularking 
    class MyThread extends Thread{
        String lock1 = "";
        String lock2 = "";
        
        public void run(){
            System.out.println(Thread.currentThread().getName() + " run");
            
            synchronized (lock1) { //标记1
                System.out.println(Thread.currentThread().getName());
                synchronized (lock2) {//标记2
                    try {
                        System.out.println("before lock2");
                        MyThread thread2 = new MyThread();
                        thread2.setName("thread2"); //标记3
                        thread2.start();
                        
                        lock2.wait();
                        System.out.println("after lock2");
                        
                        System.out.println("thread2 started");
                    }
                    catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    MyThread thread1 = new MyThread();
    thread1.setName("thread1"); //标记
    thread1.start();dracularking 哥们    这段code会有N个MyThread 对象   每一个MyThread 对象都有一个lock1  lock2   也就是说在run方法中的lock1 lock2 加synchronized  是没有用的   lock2.wait(); 是释放lock2   在这段code中 lock2.wait(); 释不释放lock1   下一个thread还是能进入自己的run方法  和synchronized (lock1)块   因为他有自己的lock1
      

  15.   

    ...
    这个例子有问题 但原因应该不是复制的lock 换成static 效果依旧
      

  16.   

    public class Test extends Thread {
        
        private Test dld;
        public String lock1 ="";
        public String lock2 ="";
        
        @Override
        public void run() {
            
                try {
                    System.out.println("线程启动");
                    Thread.sleep(100);
                }
                catch (InterruptedException e) {
                    // TODO 自动生成 catch 块
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + " in run");
                dld.fun();
        }
        
        public void fun(){
            synchronized (lock1) {
                synchronized (lock2) {
                    try {
                        System.out.println(Thread.currentThread().getName()
                                + " fun()方法调用");
                        lock2.wait();
                        Thread.sleep(4500);
                    }
                    catch (InterruptedException e) {
                        // TODO 自动生成 catch 块
                        e.printStackTrace();
                    }
                }
            }
        }
        
        public static void main(String []args){
            Test t1 = new Test();
            Test t2 = new Test();
            t1.start();
            t2.start();
            t1.dld = t2;                     
            t2.dld = t1;   
        }
        
    }
    这个例子能说明问题吗? 比较有没
    lock2.wait();的区别
    由于String的特殊性 两个实例中的同名属性是同一个引用
      

  17.   

    上例还有点问题 lock1和lock2不应重名
    关于lz的这个问题 我想只要在标记1处调用
    lock.wait();就成了
    虽然此时标记1所在同步块锁未必释放
      

  18.   


    public class ProducerCustomer { /**
     * @param args
     */
    private Producer p = null; private Customer c = null; public static void main(String[] args) {
    // TODO Auto-generated method stub
    ProducerCustomer pc = new ProducerCustomer();
    Producer p = pc.getProducer();
    Customer c = pc.getCustomer(); Thread th1 = new Thread(p, "th1");
    Thread th3 = new Thread(p, "th3"); Thread th2 = new Thread(c, "th2");
    Thread th4 = new Thread(c, "th4"); th1.start();
    th3.start();
    th2.start();
    th4.start(); } public Producer getProducer() {
    if (p == null) {
    p = new Producer(this);
    } return p;
    } public Customer getCustomer() {
    if (c == null) {
    c = new Customer(this);
    } return c;
    } public synchronized void produce() {
    while (true) {
    try {
    Thread.currentThread().sleep(500);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    System.out.println("" + Thread.currentThread().getName() + "  "
    + " I have produced a product ");
    try {
    notify();
    synchronized (getProducer()) { //整段 code 只有一个produce对象
    getProducer().wait();
    }
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    } } public synchronized void custom() {
    while (true) {
    try {
    Thread.currentThread().sleep(500);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    System.out.println("" + Thread.currentThread().getName() + "  "
    + " I have used the product ");
    try {
    notify();
    synchronized (getProducer()) { //整段 code 只有一个custom对象
    getProducer().wait();
    }
    wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    } } class Producer implements Runnable {
    private ProducerCustomer pc = null; public Producer(ProducerCustomer pc) {
    this.pc = pc;
    } public void run() {
    pc.produce();
    }
    } class Customer implements Runnable {
    private ProducerCustomer pc = null; public Customer(ProducerCustomer pc) {
    this.pc = pc;
    } public void run() {
    pc.custom();
    }
    }}这段程序有2个run方法   各有两个线程分别在里面跑  当th1进入produce()时,他获得ProducerCustomer.this锁,th2,th3,th4均处于等待状态
    当th1执行到getProducer().wait();时,th1释放getProducer()锁,但此时ProducerCustomer.this锁仍未释放,所以th2,th3,th4仍旧不会执行,所以这段code打印出来的结果只有一条sysout语句
      

  19.   

    custom() 方法里多写了个 wait()   不影响结论