实在惭愧,java开发多年,多线程运用一直不多,该知识点理解也不够,不怎么会用。赶上使用多线程 生产者、消费者模式,学习下该知识点。

synchronized  获取锁

wait 阻塞本线程,释放对象锁。该线程会在该代码处阻塞,不往下执行。

notify 释放对象锁,通知其他被阻塞的线程可以被唤醒。

Thread.sleep()与Object.wait()二者都可以暂停当前线程,释放CPU控制权,主要的区别在于Object.wait()在释放CPU同时,释放了对象锁的控制。

IllegalMonitorStateException异常发生是由于程序员没有注意notify(),notify(),wait()方法的使用条件,没有真正理解线程同步机制。如果当前的线程不是此对象锁的所有者,却调用该对象的notify(),notify(),wait()方法时抛出该异常。个人暂时理解为若线程没有持有任何锁,而调用这几个方法,会出现该异常。

 package socket;

 public class Producer2 extends Thread {

     public class Producer extends Thread {

         private Share shared;
         private int   number;

         public Producer(Share s, int number) {
             shared = s;
             this.number = number;
         }

         public void run() {
             for (int i = 0; i < 10; i++) {
                 System.out.println("[00]");
                 shared.put(i);
                 System.out.println("生产者" + this.number + " 输出的数据为:" + i);
                  try {
                  sleep((int) (Math.random() * 100));//这里一定要加,否则(注释掉sleep代码)消费者可能会暂时取不到cpu控制权,而没办法打印出信息。而此时消费者get()方法中已经执行notify方法,导致生产者被唤醒,继续生产执行put(),给人误导没有消费。实际已经消费而只是未打印而已。
                  } catch (InterruptedException e) {
                  }
                 System.out.println("[000]");
             }
         }
     }

     // 共享资源对象

     public class Share {

         private int     contents;
         private boolean available = false;

         public synchronized int get() {
             System.out.println("[1]");
             if (available == false) {
                 try {
                     System.out.println("[2]");
                     wait();
                     System.out.println("[3]");
                 } catch (InterruptedException e) {
                 }
             }
             available = false;
             System.out.println("[4]");
             notify();// 通知其他使用该对象的线程,你们可以在适当的时间被唤醒了。只要我锁一释放(synchronized方法体执行完),其他线程就有被唤醒的可能,就有可能把锁抢过去执行了。
             System.out.println("[5]");
             return contents;
         }

         public synchronized void put(int value) {
             System.out.println("[6]");
             if (available == true) {
                 try {
                     System.out.println("[7]");
                     wait();// 我不使用该对象了,本线程睡觉了,现在是其他对象被唤醒的时机,你们可以在被wait的地方继续执行了
                     System.out.println("[8]");
                 } catch (InterruptedException e) {
                 }
             }
             available = true;
             System.out.println("[9]");
             notify();//这里也要加,原因是,用于唤醒其他线程,不加的话,在本线程睡觉后,消费者线程不被唤醒,生产者线程唤醒其他线程的notify方法没有机会执行,那生产者线程会一直睡大觉了。
             System.out.println("[10]");
             contents = value;
         }
     }

     // 消费者程序

     public class Consumer extends Thread {

         private Share shared;
         private int   number;

         public Consumer(Share s, int number) {
             shared = s;
             this.number = number;
         }

         public void run() {
             int value = 0;
             for (int i = 0; i < 10; i++) {
                 System.out.println("[11]");
                 value = shared.get();
                 System.out.println("消费者" + this.number + " 得到的数据为:" + value);
             }
         }
     }

     // 主程序

     public static void main(String[] args) {
         Producer2 test = new Producer2();
         Share s = test.new Share();
         Producer p = test.new Producer(s, 1);
         Consumer c = test.new Consumer(s, 1);
         p.start();
         try {
             Thread.sleep(10);
         } catch (InterruptedException e) {
             // TODO Auto-generated catch block
             e.printStackTrace();
         }
         c.start();
     }
 }

多线程中wait、notify理解的更多相关文章

  1. Java多线程中wait, notify and notifyAll的使用

    本文为翻译文章,原文地址:http://www.journaldev.com/1037/java-thread-wait-notify-and-notifyall-example 在Java的Obje ...

  2. java多线程中wait/notify/sleep/join/yield方法以及多线程的六种状态

    刚开始学线程的时候也是被这几个方法搞的云里雾里的,尤其是一开始看的毕老师的视频,老师一直在强调执行权和执行资格,看的有点懵逼,当然不是说毕老师讲的不好,就是自己有点没听明白,后来复习看了一些其他的博客 ...

  3. python多线程中join()的理解

    在 Python 的多线程编程中,经常碰到 thread.join()这样的代码.那么今天咱们用实际代码来解释一下 join 函数的作用. 第一,当一个进程启动之后,会默认产生一个主线程,因为线程是程 ...

  4. 多线程中Object的wait(),notify()和Condition的wait()和singal()对锁的关联

    通常将共享资源的操作放置在Sysnchronized定义的区域内,这样当其他线程也获取到这个锁时,必须的等待锁被释放时才能进入该区域.Object为任意一个对象,每个对象都存在一个标志位,并具有两个值 ...

  5. 多线程中的&quot;断点&quot;续传《notify()和wait()》

    眼下在做一个项目.关于软件管理与下载的,预计项目提交日期定在6月9号.项目做了有20天了,可是在一个功能上卡住了.在这个项目中有一个功能----APK的下载须要实现. 相信大家都玩过非常多关于下载AP ...

  6. Java多线程中线程间的通信

    一.使用while方式来实现线程之间的通信 package com.ietree.multithread.sync; import java.util.ArrayList; import java.u ...

  7. python 多线程中的同步锁 Lock Rlock Semaphore Event Conditio

    摘要:在使用多线程的应用下,如何保证线程安全,以及线程之间的同步,或者访问共享变量等问题是十分棘手的问题,也是使用多线程下面临的问题,如果处理不好,会带来较严重的后果,使用python多线程中提供Lo ...

  8. Java多线程中的常用方法

    本文将带你讲诉Java多线程中的常用方法   Java多线程中的常用方法有如下几个 start,run,sleep,wait,notify,notifyAll,join,isAlive,current ...

  9. c#语言-多线程中的锁系统(一)

    介绍 平常在多线程开发中,总避免不了线程同步.本篇就对net多线程中的锁系统做个简单描述.   目录 一:lock.Monitor        1:基础.        2: 作用域.       ...

  10. 如何在多线程中调用winform窗体控件

    由于 Windows 窗体控件本质上不是线程安全的.因此如果有两个或多个线程适度操作某一控件的状态(set value),则可能会迫使该控件进入一种不一致的状态.还可能出现其他与线程相关的 bug,包 ...

随机推荐

  1. Agc017_E Jigsaw

    传送门 题目大意 有$n$块拼图,每一块都由左中右三个部分组成,每块拼图中间部分是高为$H$的长方形,对于第$i$块品推左侧是高为$A_i$距离底部为$C_i$的长方体,右侧是高位$B_i$距底部为$ ...

  2. win7下vs2010开发atl服务

    问题一: 编译服务后,提示出下错误 Microsoft.CppCommon.targets(113,5): error MSB3073: 命令 " ***.exe "  /RegS ...

  3. 服务器FTP配置

    一.如果没有安装FTP服务器,安装如下: 二.添加SSL证书 三.给证书起一个有意义的名字就可以了 四.FTP  SSL设置 五.FTP 身份验证: 进入-如果开启自己需要的-我这里是需要用户输入密码 ...

  4. HDUj2612(两个起点找到最近的目的地)

    Find a way Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  5. Java 的 Tuple 元组数据类型

    元组类型,即 Tuple 常在脚本语言中出现,例如 Scala 的 ("Unmi", "china@qq.com", "blahbla"). ...

  6. Makefile经典教程

    转自:http://blog.csdn.net/ruglcc/article/details/7814546/       makefile很重要 什么是makefile?或许很多Winodws的程序 ...

  7. lvs-nat搭建httpd

    拓扑图: #172.16.252.10 [root@~ localhost]#route -n Kernel IP routing table Destination Gateway Genmask ...

  8. Python模块-logging模块(二)

    logging模块记录日志有四个主要类:logger,handler,formatter,filter logger提供了应用程序可以直接使用的接口,每个程序在输出信息之前都要获得一个Logger h ...

  9. linux日常管理-vmstat命令

    系统负载用w查看.是什么原因造成了系统负载.查看系统负载状态 命令:vmstat vmstat就查看一次 vmstat 1 每秒钟更新一次.按ctrl+c取消. vmstat 1 5 每秒钟更新一次, ...

  10. Devexpress GridControl

    1.隐藏“Drag a column header here to group by that column”如下: 选择gridview->属性 选择OptionView->ShowGr ...