1. /*
  2. class Person{
  3. String name;
  4. String sex;
  5. boolean flag = true;
  6. public void setPerson(String name, String sex){
  7. this.sex=sex;
  8. this.name=name;
  9. }
  10. }
  11. class Input implements Runnable{
  12. int x=0;
  13. Person p;
  14. Input(Person p){
  15. this.p=p;
  16. }
  17. public void run(){
  18. while(true){
  19. if(x==1){
  20. p.setPerson("hjz", "man");
  21. }
  22. else p.setPerson("哈哈哈", "女女女女");
  23. x=(x+1)%2;
  24. }
  25. }
  26. }
  27.  
  28. class Output implements Runnable{
  29. int x=0;
  30. Person p;
  31. Output(Person p){
  32. this.p=p;
  33. }
  34. public void run(){
  35. while(true){
  36. System.out.println(p.name + "....." + p.sex);
  37. }
  38. }
  39. }
  40. public class Test{
  41. public static void main(String[] args){
  42. Person p = new Person();
  43. new Thread(new Input(p)).start();
  44. new Thread(new Output(p)).start();
  45. }
  46. }
  47. */
  48.  
  49. /*
  50. 输出的结果:
  51. 哈哈哈.....man
  52. hjz.....man
  53. hjz.....man
  54. 哈哈哈.....man
  55. hjz.....女女女女
  56. */
  57.  
  58. //线程安全隐患出现:首先考虑到是多线程操作了同一资源,所以要用同步!
  59. /*
  60. class Person{
  61. String name;
  62. String sex;
  63. boolean flag = true;
  64. public void setPerson(String name, String sex){
  65. this.sex=sex;
  66. this.name=name;
  67. }
  68. }
  69.  
  70. class Input implements Runnable{
  71. int x=0;
  72. Person p;
  73. Input(Person p){
  74. this.p=p;
  75. }
  76. public void run(){
  77. while(true){
  78. synchronized(new Object()){
  79. if(x==1){
  80. p.setPerson("hjz", "man");
  81. }
  82. else p.setPerson("哈哈哈", "女女女女");
  83. x=(x+1)%2;
  84. }
  85. }
  86. }
  87. }
  88.  
  89. class Output implements Runnable{
  90. int x=0;
  91. Person p;
  92. Output(Person p){
  93. this.p=p;
  94. }
  95. public void run(){
  96. while(true){
  97. System.out.println(p.name + "....." + p.sex);
  98. }
  99. }
  100. }
  101. public class Test{
  102. public static void main(String[] args){
  103. Person p = new Person();
  104. new Thread(new Input(p)).start();
  105. new Thread(new Output(p)).start();
  106. }
  107. }
  108. */
  109.  
  110. //同步完成之后,发现还是出现安全隐患的情况,在考虑一下是否访问统一资源的多个线程用的是同一个锁!
  111. //本例中的应将输入输出一起同步(注意输入输出不在同一个线程之中,输出线程不会获得 Person p对象的控制权!)
  112. /* class Input implements Runnable{
  113. int x=0;
  114. Person p;
  115.  
  116. Input(Person p){
  117. this.p=p;
  118. }
  119. public void run(){
  120. while(true){
  121. synchronized(p){
  122. if(p.flag){
  123. try{
  124. p.wait();
  125. }catch(InterruptedException e){
  126. }
  127. }
  128. if(!p.flag){
  129. if(x==1){
  130. p.setPerson("hjz", "man");
  131. }
  132. else p.setPerson("哈哈哈", "女女女女");
  133. x=(x+1)%2;
  134. }
  135.  
  136. p.flag=true;
  137. p.notify();
  138.  
  139. }
  140. }
  141. }
  142. } */
  143.  
  144. //现在的代码是将同步放到函数里!真正开发过的时候就是这样实现,也就是我们多个线程同事操作一个类对象
  145. //调用该类提供的对外方法,并将调用的方法进行同步!防止安全隐患!
  146. class Person{
  147. String name;
  148. String sex;
  149. boolean flag = true;
  150. public void setPerson(String name, String sex){
  151. synchronized(this){
  152. if(!flag){
  153. try{
  154. wait();
  155. }catch(InterruptedException e){}
  156. }
  157. if(flag){
  158. this.sex=sex;
  159. try{
  160. Thread.sleep(100);
  161. }catch(InterruptedException e){}
  162. this.name=name;
  163. }
  164. flag=false;
  165. notify();
  166. }
  167. }
  168.  
  169. public void outPerson(){
  170. synchronized(this){
  171. if(flag){
  172. try{
  173. wait();
  174. }catch(InterruptedException e){}
  175. }
  176. if(!flag){
  177. System.out.println(name + "....." + sex);
  178. }
  179. flag=true;
  180. notify();
  181. }
  182. }
  183. }
  184.  
  185. class Input implements Runnable{
  186. int x=0;
  187. Person p;
  188.  
  189. Input(Person p){
  190. this.p=p;
  191. }
  192. public void run(){
  193. while(true){
  194. if(x==1){
  195. p.setPerson("hjz", "man");
  196. }
  197. else p.setPerson("哈哈哈", "女女女女");
  198. x=(x+1)%2;
  199. }
  200. }
  201. }
  202.  
  203. class Output implements Runnable{
  204. int x=0;
  205. Person p;
  206. Output(Person p){
  207. this.p=p;
  208. }
  209. public void run(){
  210. while(true){
  211. p.outPerson();
  212. }
  213. }
  214. }
  215.  
  216. public class Test{
  217. public static void main(String[] args){
  218. Person p = new Person();
  219. new Thread(new Input(p)).start();
  220. new Thread(new Output(p)).start();
  221. }
  222. }

  

java多线程的等待唤醒机制及如何解决同步过程中的安全问题的更多相关文章

  1. java基础知识回顾之java Thread类学习(八)--java多线程通信等待唤醒机制经典应用(生产者消费者)

     *java多线程--等待唤醒机制:经典的体现"生产者和消费者模型 *对于此模型,应该明确以下几点: *1.生产者仅仅在仓库未满的时候生产,仓库满了则停止生产. *2.消费者仅仅在有产品的时 ...

  2. java基础知识回顾之java Thread类学习(七)--java多线程通信等待唤醒机制(wait和notify,notifyAll)

    1.wait和notify,notifyAll: wait和notify,notifyAll是Object类方法,因为等待和唤醒必须是同一个锁,不可以对不同锁中的线程进行唤醒,而锁可以是任意对象,所以 ...

  3. java 22 - 17 多线程之等待唤醒机制(接16)

    先来一张图,看看什么叫做等待唤醒机制 接上一章的例子. 例子:学生信息的录入和获取 * 资源类:Student  * 设置学生数据:SetThread(生产者) * 获取学生数据:GetThread( ...

  4. Java第二十五天,多线程之等待唤醒机制

    当线程被创建并且被启动之后,它既不是一启动就进入了执行状态,也不是一直处于执行状态,而是具有以下多种状态: 这六种状态之间的转换关系如下: 1.等待唤醒机制 注意: (1)两个线程之间必须用同步代码块 ...

  5. Java学习:等待唤醒机制

    等待唤醒机制 线程的状态 NEW   至今尚未启动的线程处于这种状态 RUNNABLE   正在Java虚拟机中执行的线程处于这种状态 BLOCKED 受阻塞并等待某个监视器锁的线程处于这种状态 WA ...

  6. java锁在等待唤醒机制中作用

    等待的线程放在线程池wait().notify().notifyall()都使用在同步中,因为要对持有监视器(锁)的线程操作.所以要使用在同步中,因为只有同步才具有锁. 为什么这些操作的线程的方法要定 ...

  7. Android(java)学习笔记71:生产者和消费者之等待唤醒机制

    1. 首先我们根据梳理我们之前Android(java)学习笔记70中关于生产者和消费者程序思路: 2. 下面我们就要重点介绍这个等待唤醒机制: (1)第一步:还是先通过代码体现出等待唤醒机制 pac ...

  8. Android(java)学习笔记11:生产者和消费者之等待唤醒机制

    1. 首先我们根据梳理我们之前Android(java)学习笔记70中,关于生产者和消费者程序思路: 2. 下面我们就要重点介绍这个等待唤醒机制: (1)第一步:还是先通过代码体现出等待唤醒机制 下面 ...

  9. 多线程之Java中的等待唤醒机制

    多线程的问题中的经典问题是生产者和消费者的问题,就是如何让线程有序的进行执行,获取CPU执行时间片的过程是随机的,如何能够让线程有序的进行,Java中提供了等待唤醒机制很好的解决了这个问题! 生产者消 ...

随机推荐

  1. jQUery 1.9中被删除的API

    jQuery1.9删除了一些在以前版本中已经过时的api,想要把那些不够安全的.缺乏效率的.用处不大的,以及带有误导的特性统统去掉.如果你想升级你的jquery版本,但又使用了如下被删除的api的话, ...

  2. idea小技巧

    1.不使用import *:Setting=>Editor=>Code Style=>Java=>Imports=>Class count to use/Names co ...

  3. Java反射机制调用private类型的构造方法

    单例类: package singleton; public class SingletonTest { // 私有构造方法 private SingletonTest(){ System.out.p ...

  4. testng参数化及用例排序

    http://blog.sina.com.cn/s/blog_6966650401012ra0.html 一.一个简单的测试谷歌搜索 import org.testng.annotations.Tes ...

  5. 安装 webpack

    安装 webpack看好webpack 对自动压缩和文件名自动md5更名,可解决客户端缓存问题.我的安装环境为 centos linux,root用户 1.安装Node及NPM.到NodeJS官网安装 ...

  6. 浅析C语言指针问题

    首先明白c语言操作符的优先级及结合性就很容易理解了. 链接 1.关于char *s 及 char s[] char *s指向的是一个字符串对象的指针,可以理解为间接引用,比如 char *s = “1 ...

  7. 申请Google API Key

    想使用google map api 必须从google网站上获取key之后才有权限使用,但是要想申请key必须要有证明书,也就是所谓的MD5.下面一步一步来说明: 步骤1: 如果你使用的是eclips ...

  8. HTML + JS随机抽号。

    [设置第三次抽取的号码为 (张三6)]<script language="javascript"> var k = 0 ; function star(){ k++ ; ...

  9. Runtime 交换方法

    创建UIImage分类UIImage+Image.h #import<UIKit/UIKit.h> @interfaceUIImage (Image) + (__kindof UIImag ...

  10. FileInputStream和BufferedInputStream的区别

    FileInputStream 属于数据源 BufferedInputStream 属于FileInputStream的一个装饰 BufferedInputStream 有个内部缓冲区当read时会先 ...