`
HelloSure
  • 浏览: 310038 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

多线程例子:wait与notify、sleep

 
阅读更多
package sure;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


public class Test {

	private static Logger log = LoggerFactory.getLogger(Test.class);
	
    public static void main(String[] args) throws Exception {  
        final Object lock="";  
        Thread t1=new Thread(){  
            public void run(){  
                try {  
                	log.info("t1 wait begin");  
                    synchronized (lock) {  
                    	log.info("t1 get lock, wait begin");
                        lock.wait();  
                        log.info("t1 wait end,release lock");
                        lock.notifyAll();
                    }  
                    log.info("t1  wait end");  
                } catch (InterruptedException e) {  
                    e.printStackTrace();  
                }  
            }  
        };  
          
        t1.start();  
        log.info("t1 start and sleep");
        for(int i=0;i<10000001;i++){
        	if(i==10000000)
        		log.info("i end");
        }
        Thread.sleep(5000);  
        log.info("sleep(5000) end");
          
        log.info("main lock begin");  
        synchronized (lock) {
        	log.info("main get lock");
            lock.notify();
            log.info("notify");
            Thread.sleep(10000); 
            log.info("sleep 10000 end");
            log.info("main wait begin ");  
            lock.wait();  
            log.info("main wait end");  
        }  
        log.info("main lock end");  
    }  
}



日志信息如下:
2011-11-09 15:44:05,968 INFO [sure.Test] - t1 start and sleep
2011-11-09 15:44:05,968 INFO [sure.Test] - t1 wait begin
2011-11-09 15:44:05,968 INFO [sure.Test] - t1 get lock, wait begin
2011-11-09 15:44:05,984 INFO [sure.Test] - i end
2011-11-09 15:44:10,984 INFO [sure.Test] - sleep(5000) end
2011-11-09 15:44:10,984 INFO [sure.Test] - main lock begin
2011-11-09 15:44:10,984 INFO [sure.Test] - main get lock
2011-11-09 15:44:10,984 INFO [sure.Test] - notify
2011-11-09 15:44:20,984 INFO [sure.Test] - sleep 10000 end
2011-11-09 15:44:20,984 INFO [sure.Test] - main wait begin 
2011-11-09 15:44:20,984 INFO [sure.Test] - t1 wait end,release lock
2011-11-09 15:44:20,984 INFO [sure.Test] - t1  wait end
2011-11-09 15:44:20,984 INFO [sure.Test] - main wait end
2011-11-09 15:44:20,984 INFO [sure.Test] - main lock end


wait,notify,notifyAll必须在当前线程获得监视器时才能调用,即这些方法必须在同步块中才能调用。

被阻塞的线程在被notify之后,并不是马上可以执行,而是“可执行”,要到获得锁之后才能真正开始执行。

从这个例子进行各种修改可以用来加深对线程的理解。
package sure;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


public class Test {

	private static Logger log = LoggerFactory.getLogger(Test.class);
	
    public static void main(String[] args) throws Exception {  
        final Object lock="";  
        Thread t1=new Thread(){  
            public void run(){  
                try {  
                	log.info("t1 wait begin");  
                    synchronized (lock) {  
                    	log.info("t1 get lock, wait begin");
                    	Thread.sleep(5000);
                    	log.info("sleep end");
                        lock.wait();  
                        log.info("t1 wait end,release lock");
                        lock.notifyAll();
                    }  
                    Thread.sleep(5000);
                    log.info("t1  wait end");  
                } catch (InterruptedException e) {  
                    e.printStackTrace();  
                }  
            }  
        };  
          
        t1.start();  
        log.info("t1 start and sleep");
          
        log.info("main lock begin");  
        synchronized (lock) {
        	log.info("main get lock");
            lock.notify();
            log.info("notify");
            Thread.sleep(10000); 
            log.info("sleep 10000 end");
            log.info("main wait begin ");  
            lock.wait();  
            log.info("main wait end");  
        }  
        log.info("main lock end");  
       
    }  

}

日志为:
2011-11-09 16:55:19,031 INFO [sure.Test] - t1 start and sleep
2011-11-09 16:55:19,031 INFO [sure.Test] - main lock begin
2011-11-09 16:55:19,031 INFO [sure.Test] - main get lock
2011-11-09 16:55:19,031 INFO [sure.Test] - notify
2011-11-09 16:55:19,031 INFO [sure.Test] - t1 wait begin
2011-11-09 16:55:29,031 INFO [sure.Test] - sleep 10000 end
2011-11-09 16:55:29,031 INFO [sure.Test] - main wait begin 
2011-11-09 16:55:29,031 INFO [sure.Test] - t1 get lock, wait begin
2011-11-09 16:55:34,031 INFO [sure.Test] - sleep end

然后两个线程都会被阻塞,造成死锁。
这个例子进一步说明了同步的用法,另外也表明了Thread.sleep是针对当前运行线程的。

有趣的是,同样是这个代码,在另一种情况下会出现这种情况:
2011-11-09 22:06:05,930 INFO [sure.Test] - t1 start and sleep
2011-11-09 22:06:05,930 INFO [sure.Test] - t1 wait begin
2011-11-09 22:06:05,930 INFO [sure.Test] - main lock begin
2011-11-09 22:06:05,930 INFO [sure.Test] - t1 get lock, wait begin
2011-11-09 22:06:10,930 INFO [sure.Test] - sleep end
2011-11-09 22:06:10,930 INFO [sure.Test] - main get lock
2011-11-09 22:06:10,930 INFO [sure.Test] - notify
2011-11-09 22:06:20,930 INFO [sure.Test] - sleep 10000 end
2011-11-09 22:06:20,930 INFO [sure.Test] - main wait begin 
2011-11-09 22:06:20,930 INFO [sure.Test] - t1 wait end,release lock
2011-11-09 22:06:20,930 INFO [sure.Test] - main wait end
2011-11-09 22:06:20,930 INFO [sure.Test] - main lock end
2011-11-09 22:06:25,930 INFO [sure.Test] - t1  wait end

这种情况不会造成死锁阻塞。
由于这两个线程都谁都可能先进入同步块中,所以就造成了两个截然不同的情况。但是上面第一种情况就肯定是子进程先进入同步块,因为main进程用sleep拖延了。
分享到:
评论

相关推荐

    深入理解Wait、Notify和Wait与sleep区别

    在Java编程语言中,多线程是...总之,理解和熟练掌握`wait()`, `notify()`以及`sleep()`的使用对于编写高效的多线程程序至关重要。在设计并发程序时,应根据需求选择合适的方法,确保线程间的协同工作和程序的正确性。

    Java多线程wait和notify

    总结来说,Java的 `wait()` 和 `notify()` 提供了一种在多线程环境中控制线程执行的机制。通过合理使用这些方法,我们可以实现线程间的协作,精确控制子线程的运行状态。然而,这种方式虽然灵活,但管理起来相对复杂...

    java之wait,notify的用法([ 详解+实例 ])

    在Java多线程编程中,wait和notify是两个非常重要的方法,它们都是Object类的方法,用于线程之间的通信和同步。下面我们将详细解释wait和notify的用法。 wait方法 wait方法是Object类的一个方法,用于让当前线程...

    一个理解wait()与notify()的例子

    本文旨在解析一个具体的Java多线程示例代码,以帮助读者更好地理解`wait()`与`notify()`方法的作用及其实现机制。这两个方法是Java中实现线程间通信的重要手段之一,尤其在解决生产者消费者模型、读者写者问题等经典...

    Java线程中wait,await,sleep,yield,join用法总结.pdf

    public class ThreadWaitNotify { public static void main(String[] args) throws InterruptedException { DemoTest demoTest = new DemoTest(); // 使用线程池异步执行waitTest方法 ExecutorService ...

    多线程sleep,yield,wait区别

    - `wait()` 会抛出 `InterruptedException`,与 `sleep()` 类似,需要妥善处理。 - `notify()` 仅唤醒一个等待该对象的线程,而 `notifyAll()` 唤醒所有等待的线程。 - 在使用这些方法时,必须确保线程已经获得了...

    Java多线程机制(讲述java里面与多线程有关的函数)

    挂起线程通常通过调用`sleep()`或`wait()`方法实现,恢复线程可能通过`notify()`或`notifyAll()`唤醒,终止线程则可以通过`interrupt()`方法发送中断请求,但线程本身需要检查`isInterrupted()`或`...

    一个简单的多线程例子,启动线程与终止线程。

    总之,这个简单的多线程例子展示了创建、启动和停止线程的基本步骤。通过理解和实践这些概念,开发者可以更好地设计和优化多线程应用程序,以满足高并发环境的需求。在深入学习多线程时,还要关注线程安全、性能优化...

    Java多线程通信wait()和notify()代码实例

    "Java多线程通信wait()和notify()代码实例" Java多线程通信是Java编程语言中一个重要的概念,它允许程序同时执行多个线程,以提高程序的效率和响应速度。在Java中,多线程通信主要通过wait()和notify()方法实现,...

    多线程经典例子

    了解了多线程的基本概念和应用后,我们来看一下与标签`tthread`相关的知识点。在Java中,`tthread`可能是一个自定义的线程类,它扩展了`Thread`类或实现了`Runnable`接口。自定义线程类可以重写`run()`方法,实现...

    java多线程例子.pdf

    标题和描述中并未直接提供关于Java多线程的具体例子,但是从给定的【部分内容】中我们可以提取和概括出多个关于Java多线程编程的知识点。 1. Java多线程基础概念: Java多线程是Java语言支持并发编程的一个重要...

    java多线程Demo

    在多线程环境下,可能会出现数据竞争问题,为了解决这个问题,Java提供了多种同步机制,如synchronized关键字、wait/notify机制、Lock锁(ReentrantLock)等。synchronized用于控制对共享资源的访问,而wait/notify...

    java多媒体与多线程处理实验

    ### Java多媒体与多线程处理实验知识点概览 #### 一、实验目标解析 本次实验旨在深入探索Java中多线程处理与多媒体应用的核心技术,具体目标包括: 1. **理解线程概念**:线程是操作系统能够进行运算调度的最小...

    java多线程示例

    在Java编程语言中,多线程是核心特性之一,它允许程序同时执行多个任务,从而提高了应用程序的效率和响应速度。本示例着重探讨如何在Java中实现和管理多线程,以及它带来的挑战和解决方案。 一、Java多线程基础 1. ...

    Java语言多线程编程讲义

    本文对Java语言的多线程编程进行了详细的讲解,涵盖了Java的线程机制、线程的创建、执行、结束、优先级、状态及状态间的转换、共享访问与线程同步、wait和notify在线程间的交互、Thread类的其他重要方法等方面的内容...

    多线程】_认识多线程

    本文将深入探讨多线程的概念、创建与使用,以及在实际应用中需要注意的事项。 一、多线程的基本概念 1. 线程:线程是操作系统分配处理器时间的基本单元,一个进程可以包含一个或多个线程。每个线程都有自己独立的...

    java多线程例子!.doc

    让我们深入探讨一下这个例子以及与多线程相关的知识点。 首先,创建线程主要有两种方式:继承`Thread`类和实现`Runnable`接口。在这个例子中,选择了第一种方式,即创建了一个名为`ThreadTest`的类,它直接继承自`...

    JVM线程状态和Thread.sleep的实现原理探究.pdf

    在探究JVM线程状态以及Thread.sleep的实现原理时,我们首先需要了解Java线程与操作系统...理解线程状态以及这些状态之间的转换机制,有助于开发者在设计多线程程序时作出更为合理的决策,以提高程序的性能和可靠性。

    java一个多线程的经典例子.doc

    3. **Java多线程例子**:文档中的例子创建了两个线程,`thread1`和`thread2`。`thread1`是通过继承`Thread`类实现的,而`thread2`是通过实现`Runnable`接口并传递给`Thread`构造函数实现的。两者都覆盖了`run()`方法...

    java多线程基础资料

    10. sleep()和wait()方法:sleep()方法让当前线程暂停指定时间后继续执行,而wait()方法则使线程进入等待状态,直到被notify()或notifyAll()唤醒。 以上只是Java多线程基础知识的一部分,深入学习还包括线程池的...

Global site tag (gtag.js) - Google Analytics