package concurrency;import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;public class NotifyVsNotifyAll { public static void main(String[] args) throws Exception{

ExecutorService exec = Executors.newCachedThreadPool();
for(int i = 0; i < 5; i++){
exec.execute(new Task());
}
exec.execute(new Task2());
TimeUnit.SECONDS.sleep(1);
Task.blocker.prod();
System.out.println(" the end of the programs ! ");
}
}
class Blocker{
synchronized void waitingCall(){
try{
while(!Thread.interrupted()){
System.out.println(Thread.currentThread() + " is waiting !!!");
wait();
System.out.println(Thread.currentThread() + "has done!!!");
}
}catch(Exception exp){

}
}
synchronized void prod(){
System.out.println(Thread.currentThread() + " prod() !");
notify();
}
synchronized void prodAll(){
notifyAll();
}
}class Task implements Runnable{
static Blocker blocker  = new Blocker();
@Override
public void run() {
// TODO Auto-generated method stub
blocker.waitingCall();
}
}class Task2 implements Runnable{
static Blocker blocker  = new Blocker();
@Override
public void run() {
// TODO Auto-generated method stub
blocker.waitingCall();
}
}/*output:
Thread[pool-1-thread-1,5,main] is waiting !!!
Thread[pool-1-thread-3,5,main] is waiting !!!
Thread[pool-1-thread-5,5,main] is waiting !!!
Thread[pool-1-thread-2,5,main] is waiting !!!
Thread[pool-1-thread-4,5,main] is waiting !!!
Thread[pool-1-thread-6,5,main] is waiting !!!
Thread[main,5,main] prod() !
 the end of the programs ! 
Thread[pool-1-thread-1,5,main]has done!!!
Thread[pool-1-thread-1,5,main] is waiting !!!
*/
这个是java编程思想上面的一个题目,我改了一下,我就是想请教一下大神,
为何结果是上面那样的,因为Task中的blocker只有一个,那么当一个线程
调用waitingCall()的时候,其他的线程应该就要等待了呀,为什么还会出现
Thread[pool-1-thread-3,5,main] is waiting !!!
Thread[pool-1-thread-5,5,main] is waiting !!!
Thread[pool-1-thread-2,5,main] is waiting !!!
Thread[pool-1-thread-4,5,main] is waiting !!!
这几个输出呢?这不就表示waitingCall在第一个线程执行等待的时候其它的
线程也能够进入到waitingCall中了么?
坐等大神回复,一直在线到10点半~concurrencyjavathread

解决方案 »

  1.   

    当然都能进入waitingCall了,task和task2中的blocker跟本就不是同一个对象,所以达不到锁效果,所以各自访问各自的,也就出现了这个结果。
      

  2.   


    嘿嘿  小弟知道task和task2中的blocker不是同一个对象所以我问的是
    Thread[pool-1-thread-3,5,main] is waiting !!!
    Thread[pool-1-thread-5,5,main] is waiting !!!
    Thread[pool-1-thread-2,5,main] is waiting !!!
    Thread[pool-1-thread-4,5,main] is waiting !!!
    为何会出现因为new Task()总共加入了5个到exec中,
    为何第一个进去了,后面4个也进去了。
    blocker在Task中可就一个呀哥哥
      

  3.   


    嘿嘿  小弟知道task和task2中的blocker不是同一个对象所以我问的是
    Thread[pool-1-thread-3,5,main] is waiting !!!
    Thread[pool-1-thread-5,5,main] is waiting !!!
    Thread[pool-1-thread-2,5,main] is waiting !!!
    Thread[pool-1-thread-4,5,main] is waiting !!!
    为何会出现因为new Task()总共加入了5个到exec中,
    为何第一个进去了,后面4个也进去了。
    blocker在Task中可就一个呀哥哥晕你for(int i = 0; i < 5; i++){
    exec.execute(new Task());
    }这么写,这个new Task();说明了什么???这可是生成了5个Tank对象实例啊,他们的blocker能是同一个么
      

  4.   


    嘿嘿  小弟知道task和task2中的blocker不是同一个对象所以我问的是
    Thread[pool-1-thread-3,5,main] is waiting !!!
    Thread[pool-1-thread-5,5,main] is waiting !!!
    Thread[pool-1-thread-2,5,main] is waiting !!!
    Thread[pool-1-thread-4,5,main] is waiting !!!
    为何会出现因为new Task()总共加入了5个到exec中,
    为何第一个进去了,后面4个也进去了。
    blocker在Task中可就一个呀哥哥晕你for(int i = 0; i < 5; i++){
    exec.execute(new Task());
    }这么写,这个new Task();说明了什么???这可是生成了5个Tank对象实例啊,他们的blocker能是同一个么static Blocker blocker  = new Blocker();是静态的呀  所以这5个task应该是共享一个静态变量的呀是不是的?难道是我理解错了?
      

  5.   


    嘿嘿  小弟知道task和task2中的blocker不是同一个对象所以我问的是
    Thread[pool-1-thread-3,5,main] is waiting !!!
    Thread[pool-1-thread-5,5,main] is waiting !!!
    Thread[pool-1-thread-2,5,main] is waiting !!!
    Thread[pool-1-thread-4,5,main] is waiting !!!
    为何会出现因为new Task()总共加入了5个到exec中,
    为何第一个进去了,后面4个也进去了。
    blocker在Task中可就一个呀哥哥晕你for(int i = 0; i < 5; i++){
    exec.execute(new Task());
    }这么写,这个new Task();说明了什么???这可是生成了5个Tank对象实例啊,他们的blocker能是同一个么static Blocker blocker  = new Blocker();是静态的呀  所以这5个task应该是共享一个静态变量的呀是不是的?难道是我理解错了?你没错,是我看错了,不好意思,嘿嘿嘿。是这样的,你说的都对。但是System.out.println(Thread.currentThread() + " is waiting !!!");下就是wait()方法,wait()的作用就是线程暂停而且释放掉锁,所以其它和它共用锁的线程能够进入,同样,第二个进入的也wait(),再第三个进入,直到第五个,最后他们都是等待,而且只有调用notify()后,wait才结束,等待的线程才能继续执行。问题是这里没有调用notify()啊,所以就是现在这个情况
      

  6.   


    嘿嘿  小弟知道task和task2中的blocker不是同一个对象所以我问的是
    Thread[pool-1-thread-3,5,main] is waiting !!!
    Thread[pool-1-thread-5,5,main] is waiting !!!
    Thread[pool-1-thread-2,5,main] is waiting !!!
    Thread[pool-1-thread-4,5,main] is waiting !!!
    为何会出现因为new Task()总共加入了5个到exec中,
    为何第一个进去了,后面4个也进去了。
    blocker在Task中可就一个呀哥哥晕你for(int i = 0; i < 5; i++){
    exec.execute(new Task());
    }这么写,这个new Task();说明了什么???这可是生成了5个Tank对象实例啊,他们的blocker能是同一个么static Blocker blocker  = new Blocker();是静态的呀  所以这5个task应该是共享一个静态变量的呀是不是的?难道是我理解错了?你没错,是我看错了,不好意思,嘿嘿嘿。是这样的,你说的都对。但是System.out.println(Thread.currentThread() + " is waiting !!!");下就是wait()方法,wait()的作用就是线程暂停而且释放掉锁,所以其它和它共用锁的线程能够进入,同样,第二个进入的也wait(),再第三个进入,直到第五个,最后他们都是等待,而且只有调用notify()后,wait才结束,等待的线程才能继续执行。问题是这里没有调用notify()啊,所以就是现在这个情况对对对,问题就是出在这,既然只有一个blocker,那么第一个线程进入
    waitingCall()方法后,为何后面还有其他方法能够进入waitingCall()
    ,应该是进不了的呀,因为我已经synchronized这个方法了呀,
    嘿嘿,麻烦你再帮我解释一下,麻烦哈
      

  7.   


    嘿嘿  小弟知道task和task2中的blocker不是同一个对象所以我问的是
    Thread[pool-1-thread-3,5,main] is waiting !!!
    Thread[pool-1-thread-5,5,main] is waiting !!!
    Thread[pool-1-thread-2,5,main] is waiting !!!
    Thread[pool-1-thread-4,5,main] is waiting !!!
    为何会出现因为new Task()总共加入了5个到exec中,
    为何第一个进去了,后面4个也进去了。
    blocker在Task中可就一个呀哥哥晕你for(int i = 0; i < 5; i++){
    exec.execute(new Task());
    }这么写,这个new Task();说明了什么???这可是生成了5个Tank对象实例啊,他们的blocker能是同一个么static Blocker blocker  = new Blocker();是静态的呀  所以这5个task应该是共享一个静态变量的呀是不是的?难道是我理解错了?你没错,是我看错了,不好意思,嘿嘿嘿。是这样的,你说的都对。但是System.out.println(Thread.currentThread() + " is waiting !!!");下就是wait()方法,wait()的作用就是线程暂停而且释放掉锁,所以其它和它共用锁的线程能够进入,同样,第二个进入的也wait(),再第三个进入,直到第五个,最后他们都是等待,而且只有调用notify()后,wait才结束,等待的线程才能继续执行。问题是这里没有调用notify()啊,所以就是现在这个情况对对对,问题就是出在这,既然只有一个blocker,那么第一个线程进入
    waitingCall()方法后,为何后面还有其他方法能够进入waitingCall()
    ,应该是进不了的呀,因为我已经synchronized这个方法了呀,
    嘿嘿,麻烦你再帮我解释一下,麻烦哈
    就是刚才我说的啊,虽然synchronized让这个线程得到锁,并且其它和他共用锁的线程不能进入,但是,问题是这第一个线程执行时,执行了一个wait()方法啊,这个wait()方法虽然只是让这个线程暂停,最重要的是,在这个线程暂停后,也释放了线程锁,也就是说这个锁已经不在这个线程手中了,这时候还有另外4个线程在等待着这个锁,所以一旦第一个线程wait()了,另外的4个正在阻塞的线程就会去抢这个被第一个线程释放的锁,谁抢到谁执行。而同理,这个抢到锁的线程也会扫行wait()方法,这时锁又一次释放,这时还有3个线程去抢这个锁。至于第一个,因为他处于wait()状态下,所以在锁没有执行nitify()方法之前,它不会去抢这个锁。以此类推,直到5个锁都处于wait()状态,都不再执行,这时候也就是常说的“死锁”。这次懂了吧???
      

  8.   


    嘿嘿  小弟知道task和task2中的blocker不是同一个对象所以我问的是
    Thread[pool-1-thread-3,5,main] is waiting !!!
    Thread[pool-1-thread-5,5,main] is waiting !!!
    Thread[pool-1-thread-2,5,main] is waiting !!!
    Thread[pool-1-thread-4,5,main] is waiting !!!
    为何会出现因为new Task()总共加入了5个到exec中,
    为何第一个进去了,后面4个也进去了。
    blocker在Task中可就一个呀哥哥晕你for(int i = 0; i < 5; i++){
    exec.execute(new Task());
    }这么写,这个new Task();说明了什么???这可是生成了5个Tank对象实例啊,他们的blocker能是同一个么static Blocker blocker  = new Blocker();是静态的呀  所以这5个task应该是共享一个静态变量的呀是不是的?难道是我理解错了?你没错,是我看错了,不好意思,嘿嘿嘿。是这样的,你说的都对。但是System.out.println(Thread.currentThread() + " is waiting !!!");下就是wait()方法,wait()的作用就是线程暂停而且释放掉锁,所以其它和它共用锁的线程能够进入,同样,第二个进入的也wait(),再第三个进入,直到第五个,最后他们都是等待,而且只有调用notify()后,wait才结束,等待的线程才能继续执行。问题是这里没有调用notify()啊,所以就是现在这个情况对对对,问题就是出在这,既然只有一个blocker,那么第一个线程进入
    waitingCall()方法后,为何后面还有其他方法能够进入waitingCall()
    ,应该是进不了的呀,因为我已经synchronized这个方法了呀,
    嘿嘿,麻烦你再帮我解释一下,麻烦哈
    就是刚才我说的啊,虽然synchronized让这个线程得到锁,并且其它和他共用锁的线程不能进入,但是,问题是这第一个线程执行时,执行了一个wait()方法啊,这个wait()方法虽然只是让这个线程暂停,最重要的是,在这个线程暂停后,也释放了线程锁,也就是说这个锁已经不在这个线程手中了,这时候还有另外4个线程在等待着这个锁,所以一旦第一个线程wait()了,另外的4个正在阻塞的线程就会去抢这个被第一个线程释放的锁,谁抢到谁执行。而同理,这个抢到锁的线程也会扫行wait()方法,这时锁又一次释放,这时还有3个线程去抢这个锁。至于第一个,因为他处于wait()状态下,所以在锁没有执行nitify()方法之前,它不会去抢这个锁。以此类推,直到5个锁都处于wait()状态,都不再执行,这时候也就是常说的“死锁”。这次懂了吧???
    wait释放锁sleep不释放锁,我记反了,谢谢你哈
      

  9.   


    嘿嘿  小弟知道task和task2中的blocker不是同一个对象所以我问的是
    Thread[pool-1-thread-3,5,main] is waiting !!!
    Thread[pool-1-thread-5,5,main] is waiting !!!
    Thread[pool-1-thread-2,5,main] is waiting !!!
    Thread[pool-1-thread-4,5,main] is waiting !!!
    为何会出现因为new Task()总共加入了5个到exec中,
    为何第一个进去了,后面4个也进去了。
    blocker在Task中可就一个呀哥哥晕你for(int i = 0; i < 5; i++){
    exec.execute(new Task());
    }这么写,这个new Task();说明了什么???这可是生成了5个Tank对象实例啊,他们的blocker能是同一个么static Blocker blocker  = new Blocker();是静态的呀  所以这5个task应该是共享一个静态变量的呀是不是的?难道是我理解错了?你没错,是我看错了,不好意思,嘿嘿嘿。是这样的,你说的都对。但是System.out.println(Thread.currentThread() + " is waiting !!!");下就是wait()方法,wait()的作用就是线程暂停而且释放掉锁,所以其它和它共用锁的线程能够进入,同样,第二个进入的也wait(),再第三个进入,直到第五个,最后他们都是等待,而且只有调用notify()后,wait才结束,等待的线程才能继续执行。问题是这里没有调用notify()啊,所以就是现在这个情况对对对,问题就是出在这,既然只有一个blocker,那么第一个线程进入
    waitingCall()方法后,为何后面还有其他方法能够进入waitingCall()
    ,应该是进不了的呀,因为我已经synchronized这个方法了呀,
    嘿嘿,麻烦你再帮我解释一下,麻烦哈

    大神,我怎么觉得这个不是死锁啊,最后都wait了,没法竞争资源了