Wait,Notify,Sleep 区别 新手看

来自百度文库

java中的wait()和notify()使用实例

本例子实现了两个线程,每个线程输出1到100的数字。

第一个线程输出1-10,停止,通知第二个线程 输出1-10 第二个线程停止 通知第一个线程 输出11-20 ...

实现的要点是在Java中,每个对象都有个对象锁标志(Object lock flag)与之想关联,当一个线程A调用对象的一段synchronized代码时,

它首先要获取与这个对象关联的对象锁标志,然后执行相应的代码,执行结束后,把这个对象锁标志返回给对象;因此,在线程A执行

synchronized代码期间,如果另一个线程B也要执行同一对象的一段synchronized代码时(不一定与线程A执行的相同),它将

要等到线程A执行完后,才能继续....

如何利用wait() notify() notifyAll()?

在synchronized代码被执行期间,线程可以调用对象的wait()方法,释放对象锁标志,进入等待状态,并且可以调用notify()或者

notifyAll()方法通知正在等待的其他线程。notify()通知等待队列中的第一个线程,notifyAll()通知的是等待队列中的所有线程。

package jdeveloper.study;

import java.lang.Runnable;

import java.lang.Thread;

public class DemoThread implements Runnable{

public DemoThread() {

TestThread testthread1 = new TestThread(this,"1");

TestThread testthread2 = new TestThread(this,"2");

testthread2.start();

testthread1.start();

}

public static void main(String[] args) {

DemoThread demoThread1 = new DemoThread();

}

public void run(){

TestThread t = (TestThread) Thread.currentThread();

try{

if (!t.getName().equalsIgnoreCase("1")) {

synchronized(this) {

wait();

}

}

while(true){

System.out.println("@time in thread"+ t.getName()+ "="+ t.increaseTime());

if(t.getTime()%10 == 0) {

synchronized(this) {

System.out.println("****************************************");

notify();

if ( t.getTime()==100 ) break;

wait();

}

}

}

}catch(Exception e){e.printStackTrace();}

}

}

class TestThread extends Thread{

private int time = 0 ;

public TestThread(Runnable r,String name){

super(r,name);

}

public int getTime(){

return time;

}

public int increaseTime (){

return ++time;

}

}

Java的线路同步示例(synchronized、wait和notify)

从网上找到的代码(随便改的)。比较清晰地展示了wait和notify的运行机制。

package com.wubuku.mytest;

public class ThreadingExample {

public static void main(String args[]) {

Thread[] threads = new Thread[2];

for (int count = 0; count < threads.length; count++) {

threads[count] = new ThreadCounter(count);

threads[count].start();

}

}

private static class ThreadCounter extends Thread {

/**

* 在没有同步的情况下,这个方法会打印出不定顺序的数字

*/

public static void count() {

for (int count = 1; count <= 5; count++)

System.out.print(count + " ");

}

public static Object synchronizeVariable = "locking variable";

private int threadNo;

public ThreadCounter(int threadNo) {

this.threadNo = threadNo;

}

public void run() {

countWithSync();

}

/**

* 在有同步的情况下,能打印出这样顺序的数字: 1 1 2 2 3 3 4 4 5 5

*/

private void countWithSync() {

synchronized (synchronizeVariable) {

for (int count = 1; count <= 5; count++) {

System.out.println("[thread_" + threadNo + " print:]"

+ count + " ");

synchronizeVariable.notifyAll();

if (count < 5) {

System.out.println("[thread_" + threadNo

+ " sleep zzz...] ");

try {

synchronizeVariable.wait();

} catch (InterruptedException error) {

}

System.out.println("[thread_" + threadNo + " wakup!] ");

}

}

}

}

}

}

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

  下面是我原来在CSDN论坛上看到的一个贴子,涉及到同步,wait(),notify()等概念的理解,我试着根据原来的一些回复和Think in Java上的相关概念将wait()和notify()这两个方法剖析了一下,欢迎指教.

  问题如下:

//分析这段程序,并解释一下,着重讲讲synchronized、wait(),notify 谢谢!

class ThreadA

{

public static void main(String[] args)

{

ThreadB b=new ThreadB();

b.start();

System.out.println("b is start....");

synchronized(b)//括号里的b是什么意思,起什么作用?

{

try

{

System.out.println("Waiting for b to complete...");

b.wait();//这一句是什么意思,究竟让谁wait?

System.out.println("Completed.Now back to main thread");

}catch (InterruptedException e){}

}

System.out.println("Total is :"+b.total);

}

}

class ThreadB extends Thread

{

int total;

public void run()

{

synchronized(this)

{

System.out.println("ThreadB is running..");

for (int i=0;i<100;i++ )

{

total +=i;

System.out.println("total is "+total);

}

notify();

}

}

}

  要分析这个程序,首先要理解notify()和wait(),为什么在前几天纪录线程的时候没有纪录这两个方法呢,因为这两个方法本来就不属于 Thread类,而是属于最底层的object基础类的,也就是说不光是Thread,每个对象都有notify和wait的功能,为什么?因为他们是用来操纵锁的,而每个对象都有锁,锁是每个对象的基础,既然锁是基础的,那么操纵锁的方法当然也是最基础了.

  再往下看之前呢,首先最好复习一下Think in Java的14.3.1中第3部分内容:等待和通知,也就是wait()和notify了.

  按照Think in Java中的解释:"wait()允许我们将线程置入“睡眠”状态,同时又“积极”地等待条件发生改变.而且只有在一个notify()或notifyAll()发生变化的时候,线程才会被唤醒,并检查条件是否有变."

  我们来解释一下这句话.

  "wait()允许我们将线程置入“睡眠”状态",也就是说,wait也是让当前线程阻塞的,这一点和sleep或者suspend是相同的.那和sleep,suspend有什么区别呢?

  区别在于"(wait)同时又“积极”地等待条件发生改变",这一点很关键,sleep和suspend无法做到.因为我们有时候需要通过同步(synchronized)的帮助来防止线程之间的冲突,而一旦使用同步,就要锁定对象,也就是获取对象锁,其它要使用该对象锁的线程都只能排队等着, 等到同步方法或者同步块里的程序全部运行完才有机会.在同步方法和同步块中,无论sleep()还是suspend()都不可能自己被调用的时候解除锁定,他们都霸占着正在使用的对象锁不放.

  而wait却可以,它可以让同步方法或者同步块暂时放弃对象锁,而将它暂时让给其它需要对象锁的人(这里应该是程序块,或线程)用,这意味着可在执行wait()期间调用线程对象中的其他同步方法!在其它情况下(sleep啊,suspend啊),这是不可能的.

  但是注意我前面说的,只是暂时放弃对象锁,暂时给其它线程使用,我wait所在的线程还是要把这个对象锁收回来的呀.wait什么?就是wait别人用完了还给我啊!

  好,那怎么把对象锁收回来呢?

  第一种方法,限定借出去的时间.在wait()中设置参数,比如wait(1000),以毫秒为单位,就表明我只借出去1秒中,一秒钟之后,我自动收回.

  第二种方法,让借出去的人通知我,他用完了,要还给我了.这时,我马上就收回来.哎,假如我设了1小时之后收回,别人只用了半小时就完了,那怎么办呢?靠!当然用完了就收回了,还管我设的是多长时间啊.

  那么别人怎么通知我呢?相信大家都可以想到了,notify(),这就是最后一句话"而且只有在一个notify()或notifyAll()发生变化的时候,线程才会被唤醒"的意思了.

  因此,我们可将一个wait()和notify()置入任何同步方法或同步块内部,无论在那个类里是否准备进行涉及线程的处理。而且实际上,我们也只能在同步方法或者同步块里面调用wait()和notify().

  这个时候我们来解释上面的程序,简直是易如反掌了.

  synchronized(b){...};的意思是定义一个同步块,使用b作为资源锁。b.wait();的意思是临时释放锁,并阻塞当前线程,好让其他使用同一把锁的线程有机会执行,在这里要用同一把锁的就是b线程本身.这个线程在执行到一定地方后用notify()通知wait的线程,锁已经用完,待notify()所在的同步块运行完之后,wait所在的线程就可以继续执行

时间: 2024-08-01 22:43:10

Wait,Notify,Sleep 区别 新手看的相关文章

Linux下Gvim 的基本操作-适合新手看

Linux下Gvim 的基本操作 vi 有三种方式 编辑方式 插入方式 命令方式在命令方式下,所有命令以“:”开始,所键入的字符系统均作为命令处理在命令方式下,按下i就会进入插入模式,用户输入的可视字符都添加到文件中,按下Esc键,就回到命令状态 基本命令光标命令:k,j,h,l-----上下左右移动光标nG-------跳转命令.n为行数,该命令立即跳转到指定的行Ctrl+G -----报告光标所在位置的行数和列数w,b----- 使光标向前或者向后跳过一个单词 编辑命令:i,a,r----在

自定义键盘~新手看

写这日志以及前面的一些简单的东西就是 纯粹的重温一下 记录下自己的点点滴滴  从runtime runloop 到 函数底层 可能是年纪大了 想回顾一下 从入行到现在本人学了java Python PHP Scala C# JS等等一系列的语言  并学以致用 希望以后能有更好的风景~~ 这篇日志很适合新手看 大神勿喷 自定义键盘 应用场景 密码输入 创建 CustomTextField 继承于UITextField KeyBoardView 继承于UIView CustomTextField.h

《程序员成长路线》之新手看高手

1.10 新手看高手 入门之前,很多程序员心里有一个高手情结.通过书籍.媒体.传说渲染,他们认为IT行业是一个高手林立的行业,好像这些高手创造了这个行业的奇迹.这些高手可能是国外的,也可能是中国的.这个高手可能是一个具体的人,也可能抽象于某些著名软件背后看不见的程序员.只知其名,不闻其声,这个时候的高手是一种无所不能的神,一种虚幻,是令程序员崇拜的偶像. 到了工作岗位之后,这种高手情结更加严重,由于新手发现自身技术水平有限,而内心想尽快摆脱这种状况,使得很多新手对高手感觉更加恐惧和渴望.我发现在

高铁、动车到底啥区别?看完彻底懂了(组图)

摘自:网易新闻 (原标题:高铁.动车到底啥区别?看完彻底懂了(组图)) 高铁与动车的区别到底在哪里?磁悬浮列车又是什么鬼?今天给你讲讲清楚! 高铁.动车到底啥区别?看完彻底懂了 一.普通列车与高铁钢轨的区别 1.普通铁路的钢轨 几十米就有个接口,火车行驶总是离不开“哐当哐当”的声音.车轮滚过钢轨连接处时,车轮震动.车厢震动.地面也震动,列车行驶一点儿都不平稳,简直就像在大风大浪的海面上行船一样,不能平稳前进,速度就不能提高,否则震动加剧就会形成翻车的事故. 2.高铁的钢轨 我们看看高铁,修路时按

JAVA多线程suspend()、resume()和wait()、notify()的区别(转载)

suspend() 和 resume() 方法:两个方法配套使用,suspend()使得线程进入阻塞状态,并且不会自动恢复,必须其对应的 resume() 被调用,才能使得线程重新进入可执行状态.典型地,suspend() 和 resume() 被用在等待另一个线程产生的结果的情 形:测试发现结果还没有产生后,让线程阻塞,另一个线程产生了结果后,调用 resume() 使其恢复.但suspend()方法很容易引起死锁问题, 已经不推荐使用了. wait() 和 notify() 方法:两个方法配

Lock的await/singal 和 Object的wait/notify 的区别(转载)

在使用Lock之前,我们都使用Object 的wait和notify实现同步的.举例来说,一个producer和consumer,consumer发现没有东西了,等待,producer生成东西了,唤醒. 线程consumer 线程producer synchronize(obj){     obj.wait();//没东西了,等待 } synchronize(obj){     obj.notify();//有东西了,唤醒 } 有了lock后,世道变了,现在是: lock.lock(); con

java web项目和java项目的区别(看清IDE本质)

想必大家在使用MyEclipse时对这两个概念不去深究.只知道是Java EE类的基本都是Web项目,而Java应用程序就是Java项目.而且很多人都愿意使用MyEclipse作为开发工具,且不说大家费尽心思去破解这个 东西,而且那么多插件在启动时的加载速度和内存占用,你甘心这么玩嘛?不甘心?继续阅读本文!无所谓,您可以去做点其他事情不要浪费时间在这里.当然本文 不去解释如何优化MyEclipse,相关说明大家更可以Google一下. Web项目是网页的编码,像jsp,servlet,strut

学习RAC小记-适合给新手看的RAC用法总结(转)

原文:http://www.jianshu.com/p/ff79a5ae0353 什么是RAC? 几乎每一篇介绍RAC的文章开头都是这么一个问题.我这篇文章是写给新手(包括我自己)看的,所以这个问题更是无法忽视. 简单的说,RAC就是一个第三方库,他可以大大简化你的代码过程. 官方的说,ReactiveCocoa(其简称为RAC)是由GitHub开源的一个应用于iOS和OS X开发的新框架.RAC具有函数式编程和响应式编程的特性. 为什么我们要学习RAC? 为了提高我们的开发效率.RAC在某些特

Lock的await/singal 和 Object的wait/notify 的区别

在使用Lock之前,我们都使用Object 的wait和notify实现同步的.举例来说,一个producer和consumer,consumer发现没有东西了,等待,produer生成东西了,唤醒. 线程consumer 线程producer synchronize(obj){     obj.wait();//没东西了,等待} synchronize(obj){     obj.notify();//有东西了,唤醒 } 有了lock后,世道变了,现在是: lock.lock(); condi