`
liusu
  • 浏览: 170062 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

Java notify() and notifyAll() test

    博客分类:
  • Java
阅读更多
程序会启动20个线程,20个线程都使用同一个sync的object(名字为SYNC)。 线程启动代码如下:

final TC[] ts = new TC[20];
        for (int i = 0; i < ts.length; i++) {
            TC target = new TC("TC " + i, SYNC1);
            Thread thread = new Thread(target);
            ts[i] = target;
            thread.start();
}

------------------------------------------------------------
接下来马上启动另外一个线程用于做notify操作。

// 一个用于停止的Thread
        new Thread(new Runnable() {
            public void run() {
                synchronized (SYNC1) {
                    int i = 10;
                    while (i > 0) {
                        System.out.println("Now will notify the thread " + i);
                        ts[i].notifySelf();
                        try {
                            SYNC1.wait(10000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        i--;
                    }
                }
            }
 }).start();

------------------------------------------------------------

启动的TC线程代码如下:

class TC implements Runnable {

    private final String name;

    private final Object sync;

    private boolean isRunning = false;

    public TC(String name, Object sync) {
        this.name = name;
        this.sync = sync;
    }

    public void run() {
        synchronized (sync) {
            while (true) {
                // 每个线程默认都加入线程池排队。这样有助于打乱线程在主线程中启动的顺序,方便后面的观测。
                if (!isRunning) {
                    try {
                        sync.wait(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    isRunning = true;
                }
                System.out.println(name + " Running .......");
                try {
                    sync.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }// Wait 1 second
            }
        }
    }

    public void notifySelf() {
        synchronized (sync) {
            System.out.println("Coming to notify the thread " + name);
            sync.notify();
        }

    }

}


---------------------------分割线---------------------------------

输出日志如下(//部分是我加的注释,不是实际输出):

Now will notify the thread 10 //首先试着notify第10个TC
Coming to notify the thread TC 10 // 也确实调用了SYNC的notify操作,但是因为当前还没有任何线程在wait,所以这个notify信号就被丢弃掉了。这个notify过去就过去了。不会影响后面的任何操作了。
TC 1 Running .......
TC 5 Running .......
TC 0 Running .......
TC 2 Running .......
TC 4 Running .......
TC 6 Running .......
TC 8 Running .......
TC 10 Running .......
TC 12 Running .......
TC 14 Running .......
TC 7 Running .......
TC 9 Running .......
TC 11 Running .......
TC 13 Running .......
TC 15 Running .......
TC 17 Running .......
TC 3 Running .......
TC 18 Running .......
TC 16 Running .......
TC 19 Running ....... //启动20线程,这20个线程启动的顺序已经被打乱了。不会从头到尾1-20的启动,而是如log显示1,5,0,2,4,6,8,10,12,14.........
//每个线程启动后会被wait(). wait的顺序是1,5,0,2,4,6,8,10,12,14.........
Now will notify the thread 9
Coming to notify the thread TC 9
TC 1 Running .......
Now will notify the thread 8
Coming to notify the thread TC 8
TC 5 Running .......
Now will notify the thread 7
Coming to notify the thread TC 7
TC 0 Running .......
Now will notify the thread 6
Coming to notify the thread TC 6
TC 2 Running .......
Now will notify the thread 5
Coming to notify the thread TC 5
TC 4 Running .......
Now will notify the thread 4
Coming to notify the thread TC 4
TC 6 Running .......
Now will notify the thread 3
Coming to notify the thread TC 3
TC 8 Running .......
Now will notify the thread 2
Coming to notify the thread TC 2
TC 10 Running .......
Now will notify the thread 1
Coming to notify the thread TC 1
TC 12 Running .......
//总共10个notify操作,但是因为启动的时候一个notify因为没有任何wait的线程给丢弃了,所以,这里只有9个notify起到了作用。他们是按照进入pool的顺序排队给notify。
//一个notify操作仅仅激活一个wait队列中的第一个线程。一对一操作。


-------------------------------分割线------------------------------
使用notifyAll代替notify。

日志输出:

Now will notify the thread 10
Coming to notify the thread TC 10 //第一个notifyAll的操作还是被丢弃了
TC 0 Running .......
TC 1 Running .......
TC 3 Running .......
TC 5 Running .......
TC 7 Running .......
TC 9 Running .......
TC 11 Running .......
TC 13 Running .......
TC 15 Running .......
TC 17 Running .......
TC 19 Running .......
TC 2 Running .......
TC 4 Running .......
TC 6 Running .......
TC 8 Running .......
TC 10 Running .......
TC 12 Running .......
TC 14 Running .......
TC 16 Running .......
TC 18 Running .......
Now will notify the thread 9
Coming to notify the thread TC 9 //一个notifyAll的操作notify所以正在wait的线程。
TC 0 Running .......
TC 1 Running .......
TC 3 Running .......
TC 5 Running .......
TC 7 Running .......
TC 9 Running .......
TC 11 Running .......
TC 2 Running .......
TC 13 Running .......
TC 15 Running .......
TC 4 Running .......
TC 17 Running .......
TC 19 Running .......
TC 6 Running .......
TC 8 Running .......
TC 10 Running .......
TC 12 Running .......
TC 14 Running .......
TC 16 Running .......
TC 18 Running .......




分享到:
评论
4 楼 arimood 2011-08-17  
想问一个问题,为什么那9个nodify后的输出会按照开始调用wait的顺序(0,1,3,5
...),当调用ts[9]的notify时,应该那20个线程都在wait的等待状态吧,那不是随机被唤醒吗?
3 楼 flower_is 2011-06-15  
看过 不错!
2 楼 763691 2010-08-05  
欢迎大家来 80791834讨论  J2EE
1 楼 caiwenhn2008 2009-12-01  
哥哥 这个例子真是精华啊  赞一个

相关推荐

Global site tag (gtag.js) - Google Analytics