实在惭愧,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();
     }
 }

最新文章

  1. css3 text-overflow属性
  2. 修正 Memo 設定為 ReadOnly 後, 無法有複製的功能
  3. /bin/dd if=/path/to/source-file of=/path/to/backup-file
  4. php 魔鬼训练
  5. spring mvc 利用匿名内部类构建返回json对象
  6. Codeforces Gym 100002 B Bricks 枚举角度
  7. Sql三种分页方法
  8. C语言基础课程 第一课 Linux环境配置小实战httpserver
  9. gitweb随记
  10. 加密传输SSL协议1_OpenSSL的安装
  11. 菜鸟玩云计算之廿二: saltstack 配置
  12. webpack学习最基本的使用方式(一)
  13. python中socket、进程、线程、协程、池的创建方式和应用场景
  14. HTML学习一_网页的基本结构及HTML简介
  15. (办公)eclipse连接github cannot open git-upload-pack(git-receive-pack)
  16. python基础之 异常处理和logging模块
  17. Facebook Cache Token Issue
  18. Jenkins远程调度Shell命令
  19. LeetCode: Set Matrix Zeroes 解题报告
  20. golang语言基础(一)

热门文章

  1. codeforces 628C C. Bear and String Distance
  2. Android中的优化技巧
  3. loj517 计算几何瞎暴力
  4. A唐纳德先生和假骰子(华师网络赛)
  5. ngCookies都做了什么
  6. uoj problem 14 DZY Loves Graph
  7. NET Remoting 最简单示例
  8. netty中的引导Bootstrap客户端
  9. TModJS:目录
  10. JWT(JSON WEB TOKEN) / oauth2 / SSL