- 浏览: 308350 次
- 性别:
- 来自: 武汉
最新评论
-
r463579217:
给一下代码demo呀
Java多线程总结之聊一聊Queue -
水土第一:
LZ 中间文章里面可能有单词拼写错误,小弟补一下。。。
pa ...
Java多线程总结之由synchronized说开去 -
xy_z487:
>> 回调函数:A调用B,同时传A给B。B执行完会 ...
深入浅出Java回调机制 -
xuxiaoyinliu:
THANKS 第一次遇到这种错误,原来是这样
String的valueOf方法传入null -
sinat_25176913:
赞赞赞,一直还在想为什么得到的是一个"null&qu ...
String的valueOf方法传入null
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拖延了。
发表评论
-
关于继承的例子
2011-11-19 15:13 1236继承是再普通不过的概念,但是你真的能玩的转吗? 父类Perso ... -
Object类分析equals、hashcode、clone
2011-11-17 21:57 1857Object类中的equals: publ ... -
成员变量的初始化
2011-11-16 16:15 1084Java会对成员变量进行自动初始化,并且在构造方法执行之前完成 ... -
关于java多线程的一篇不错的入门级文章
2011-11-14 22:42 1950虽然都是老生常谈,而且入门级,但是讲的很不错。 一、理解多线 ... -
多线程常用方法比较汇总
2011-11-15 23:07 1602从操作系统的角度讲,o ... -
多线程例子:yield
2011-11-14 20:59 1605public class Test { public ... -
String的valueOf方法传入null
2011-11-12 20:42 13813这个问题很有意思 Object obj = null; ... -
多线程例子:join
2011-11-09 23:06 1376package sure; import java. ... -
JAVA编程经验汇总
2011-11-04 21:04 1245都是一些小的点,不完 ... -
以ConcurrentHashMap为例小议并发集合类
2011-08-09 22:15 5105为了引出并发集合类ConcurrentHashMap,有必要先 ... -
聊一下Java代理那点事
2011-08-06 20:08 2017代理模式 代理模式的作用是:为其他对象提供一种代理以控制对 ... -
说说volatile关键字
2011-08-05 16:29 2356Java语言规范中指出:为 ... -
小议时序调度Timer和Quartz
2011-07-28 21:15 7223本文不是用来讲授入门手把手ABC小例子的,算是自己这段时间对T ... -
关于Java包装类装箱拆箱的小例子
2011-07-27 09:50 1475简单来说:装箱就是把值类型转变为引用类型,拆箱就是把引用类型转 ... -
深入浅出Java回调机制
2011-07-21 21:24 83343前几天看了一下Spring的部分源码,发现回调机制被大量使用, ... -
Java多线程总结之聊一聊Queue
2011-07-17 23:13 36872上个星期总结了一下synchronized相关的知识,这次将Q ... -
Java多线程总结之由synchronized说开去
2011-07-10 17:19 22485更新完毕,结贴,以后有新的想法再开新帖 这几天不断添加新内容, ... -
关于递归
2011-06-18 21:27 109算法中有调用自身,则是递归 递归算法必须是逐步有规律简化的, ... -
java的内部类与匿名类
2011-06-18 13:19 1814提起Java内部类(Inner Class)可能很多人不太熟悉 ... -
Java线程同步机制synchronized关键字的理解
2011-06-18 08:49 37由于同一进程的多个线 ...
相关推荐
3(深入理解Wait、Notify和Wait与sleep区别).rar
java多线程设计模式 线程的创建和重起 线程的同步 wait/notify/sleep机制 Worker Pattern
《JAVA多线程设计模式》PDF 下载 《Java线程 高清晰中文第二版》中文第二版(PDF) 前言 第一章 线程简介 Java术语 线程概述 为什么要使用线程? 总结 第二章 Java线程API 通过Thread类创建线程 使用Runable接口...
多线程锁 并发下的集合类 List Set Map Callable接口 线程创建的方式 callable / runnable FutureTask JUC常用辅助类 CountDownLatch (减少计数器) CyclicBarrier(加法计数器) Semaphore(信号量,流量控制) ...
分享的多线程技术不是告诉你什么是线程,线程的状态,而是我们在开发中容易踩的坑,受过的伤害。我不会告诉你什么是爱情,但是我会告诉你爱过。 一 基础: 1,Thread.sleep(0)的作用 2,为什么线程会带来性能问题 3...
1. stop() 和 suspend() 方法为何不推荐使用? 反对使用 stop(),是因为它不安全。它会解除由线程获取的所有锁定,而且...若标志指出线程应当恢复,则用一个 notify() 重新启动线程。 2. sleep() 和 wait() 有什么区别?
60、java中有几种方法可以实现一...答:多线程有两种实现方法,分别是继承Thread类与实现Runnable接口 同步的实现方面有两种,分别是synchronized,wait与notify 67、线程的基本概念、线程的基本状态以及状态之间的关系
LeetCode判断字符串是否循环 知识点总结 java基础 1、使用迭代器和for each循环查看集合元素时只能获得元素的值,不能改变元素 ...object的方法:wait(notify,notifyall),thread的方法:(sleep、join),结束
临界区的设置是为了保证其内部的代码执行的原子性和完整性,但因为临界区在任何时间只允许线程串行通过,这和我们使用多线程的初衷是相反的。如果在多线程程序中大量使用synchronized,或者不适当的使用它,会造成...
│ 高并发编程第二阶段04讲、多线程的休息室WaitSet详细介绍与知识点总结.mp4 │ 高并发编程第二阶段05讲、一个解释volatile关键字作用最好的例子.mp4 │ 高并发编程第二阶段06讲、Java内存模型以及CPU缓存不一致...
│ 高并发编程第二阶段04讲、多线程的休息室WaitSet详细介绍与知识点总结.mp4 │ 高并发编程第二阶段05讲、一个解释volatile关键字作用最好的例子.mp4 │ 高并发编程第二阶段06讲、Java内存模型以及CPU缓存不一致...
【多线程】sleep()和wait()分别是哪个类的方法,有什么区别? 79 【多线程】sleep()和yield()的区别 79 【多线程】对synchronized理解?用在代码块和方法上有什么区别? 80 【多线程】Volatile的理解 82 【*多线程】...
贾沃 注意:(以前称为Jago ) 用 Go 语言编写的简化 Java 虚拟机。 一个目标是深入学习 JVM 规范,并尝试了解 Java ... 监控、 sleep 、 wait 、 notify支持 JDK 本地方法 GC 准时制 怎么跑 构建和安装 ❯ cd ~
与cgi的区别在于servlet处于服务器进程中,它通过多线程方式运行其service方法,一个实例可以服务于多个请求,并且其实例一般不会销毁,而CGI对每个请求都产生新的进程,服务完成后就销毁,所以效率上低于servlet。...
答:Servlet与CGI的区别在于Servlet处于服务器进程中,它通过多线程方式允许其service方法,一个实例可以服务于多个请求,并且其实例一般不会被销毁,而CGI对每个请求都产生新的进程,服务完后就销毁,所以效率上...
A.sleep() B.notify() C.wait() D.join() 正确答案:B 您的答案: 本题解析: 暂无解析 2.以下标识符中,不是Java语言关键字的是()。 A.wait B.new C.long D.switch 正确答案:A 您的答案: 本题解析: 暂无解析 3....
与cgi的区别在于servlet处于服务器进程中,它通过多线程方式运行其service方法,一个实例可以服务于多个请求,并且其实例一般不会销毁,而CGI对每个请求都产生新的进程,服务完成后就销毁,所以效率上低于servlet。...
与cgi的区别在于servlet处于服务器进程中,它通过多线程方式运行其service方法,一个实例可以服务于多个请求,并且其实例一般不会销毁,而CGI对每个请求都产生新的进程,服务完成后就销毁,所以效率上低于servlet。...
//当bFull为 true ,Consumer线程才能取走数据,取走数据后bFull置为 false //当bFull为 false,Procucer线程才能写入数据,写入数据后bFull置为 true boolean bFull=false; public synchronized ...
update() 在线程同步中,为了唤醒另一个等待的线程,使用下列方法 () [单选题] * A.sleep() B.wait() C.notify()(正确答案) D. join() Java高级程序设计测试含答案全文共40页,当前为第4页。Java提供以下哪个...