`
liusu
  • 浏览: 171348 次
  • 性别: 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  
哥哥 这个例子真是精华啊  赞一个

相关推荐

    Java线程中的notifyAll唤醒操作(推荐)

    在Java中,notifyAll()方法是Object类中的方法,用于唤醒所有等待对象的线程,而不是像notify()方法那样只唤醒一个线程。 在Java线程中,notifyAll()方法经常被用来唤醒所有等待对象的线程,以便它们可以继续执行。...

    java-core-test

    - 线程同步:synchronized关键字,wait(), notify(), notifyAll()方法,以及Lock接口的使用。 - 守护线程与线程池:理解守护线程的概念,以及ExecutorService线程池的创建与管理。 8. **反射机制** - 类的加载:...

    详解Java程序并发的Wait-Notify机制

    在Java中,`wait()`, `notify()`, `notifyAll()`方法是`Object`类的成员,而不是`Thread`类的,这意味着任何对象都可以作为等待和通知的基础。 **1. 状态变量(State Variable)** 状态变量是线程间通信的关键。当...

    线程学习小Test

    综上所述,这个“线程学习小Test”通过几个具体的Java源代码文件,深入浅出地展示了Java中线程同步的重要方法及其应用。通过学习和实践这些示例,开发者能够更好地理解和掌握多线程环境下的线程同步策略,提升并发...

    等待机制与锁机制wait notify

    `wait()`、`notify()`和`notifyAll()`是Java `Object`类的三个方法,它们用于线程间的通信。这些方法必须在同步环境中(即synchronized方法或synchronized代码块)使用,否则会抛出`IllegalMonitorStateException`...

    java-test.zip_java笔试题_java面试题_site:www.pudn.com

    5. **多线程**:掌握线程的创建(通过Thread类或实现Runnable接口),同步机制(synchronized,wait(),notify(),notifyAll()),线程池(ExecutorService)以及并发工具类(如Semaphore,CyclicBarrier,...

    2006javatest

    5. **多线程**:Java提供了丰富的API来支持多线程编程,如Thread类、Runnable接口、synchronized关键字、wait()、notify()和notifyAll()方法等。 6. **输入/输出流**:包括文件I/O、字节流和字符流、缓冲流、对象...

    面向对象大胆向前 Java API 实战-Markdown格式的笔记

    单元测试与主函数(1:Unit test and main function-Java API 实战.md) 单元测试是软件开发过程中的重要环节,它能确保代码的正确性。笔记中详细介绍了JUnit框架的使用,以及如何编写和执行单元测试。同时,主函数...

    Java认证考试题目(59题)

    7. **多线程**:理解线程的概念,创建线程的方式(Thread类和Runnable接口),同步机制(synchronized关键字,wait()、notify()和notifyAll()方法),以及线程池的使用。 8. **反射API**:通过反射可以在运行时获取...

    java两个线程互相守护

    Java提供了多种工具来实现这一点,如`synchronized`关键字、`wait()`、`notify()`和`notifyAll()`方法,以及`java.util.concurrent`包下的高级并发工具。 假设我们有一个`ThreadA`和`ThreadB`,它们都需要检查对方...

    Thread Test result output

    例如,线程2在完成其任务后,调用了`notify()`方法("Sleep sometime after notify to test if others can end first"),然后退出同步块("Name:2 willExit the synchronize block"和"Name:2 End.false")。...

    Basic_Test:Java基础测试

    线程间的同步和通信可以借助synchronized关键字、wait()、notify()和notifyAll()方法。 9. **泛型**:泛型是Java 5引入的新特性,用于增强类型安全,减少类型转换的麻烦。泛型可以应用于类、接口和方法,限制可存储...

    JAVA季度编程考试试题

    学习如何创建和管理线程,同步机制(如synchronized关键字、Lock接口),以及线程间的通信(wait、notify、notifyAll)等,是提升程序并发性能的重要手段。 6. **I/O流**:Java的I/O流系统分为字节流和字符流,包括...

    java实用100例 60-100

    这部分可能包括线程的创建、同步、通信(如使用synchronized关键字、wait()、notify()和notifyAll()方法)以及线程池的使用(如ExecutorService)。 61. 异常处理:Java异常处理通过try-catch-finally语句块进行,...

    JAVA多线程模型详解

    在Java中,线程的阻塞与唤醒主要通过Object类中的wait()、notify()和notifyAll()方法实现。wait()方法会使当前线程释放对象锁并进入等待状态,直到其他线程调用相同对象的notify()或notifyAll()方法。notify()方法则...

    java经典面试 .doc

    - 同步可以通过`synchronized`关键字,`wait()`, `notify()`和`notifyAll()`来实现。`wait()`让当前持有锁的线程等待,释放锁;`sleep()`使线程暂停一段时间,不会释放锁;`notify()`唤醒一个等待的线程,但不保证...

    javar练习200题

    - 线程同步:了解synchronized关键字,wait(), notify()和notifyAll()方法,以及死锁问题。 9. **反射** - Class类:使用Class对象获取类的信息,如类名、构造器、方法等。 - 动态创建对象:通过Class的new...

    java基础学习内容

    - 调用`wait()`后,线程必须等待另一个线程调用`notify()`或`notifyAll()`来重新获得锁。 - 在调用`wait()`之前,必须先获得锁;同样,在调用`notify()`或`notifyAll()`时,也必须持有锁。 ### 二、Java文件I/O操作...

    thread-test:Java多线程基础

    Java提供了wait()、notify()和notifyAll()方法来进行线程间的通信,这些方法必须在同步块或同步方法中使用,以避免死锁和其他并发问题。 通过以上内容,我们可以了解Java多线程的基本概念和操作,但在实际应用中,...

    多线程java买票系统

    Java提供了多种线程同步机制,如`synchronized`关键字、`wait()`, `notify()`和`notifyAll()`方法、`ReentrantLock`以及`Semaphore`等。在购票系统中,可能使用了`synchronized`关键字对购票方法进行同步,确保同一...

Global site tag (gtag.js) - Google Analytics