在之前,是把生产者录入数据和消费者获取数据的所有代码都分别写在各自的类中。

这样不大好

这次把生产者和消费者部分关键代码都写入资源类中:

  1. package zl_Thread;
  2.  
  3. public class Student {
  4. // 创建对象
  5. private String name;
  6. private int age;
  7. // 创建标签
  8. private boolean flag;
  9.  
  10. // 录入数据
  11. public synchronized void set(String name, int age) {
  12.       //同步方法
  13. if (this.flag) {
  14. // 如果存在数据, 等待
  15. try {
  16. this.wait();
  17. } catch (InterruptedException e) {
  18. // TODO Auto-generated catch block
  19. e.printStackTrace();
  20. }
  21. }
  22. // 添加数据
  23. this.name = name;
  24. this.age = age;
  25.  
  26. // 更改标签
  27. this.flag = true;
  28. // 添加了数据后,唤醒
  29. this.notify();
  30. }
  31. //获取数据
  32. public synchronized void get() {
  33. //同步方法
  34. if(!this.flag){
  35. //如果没有数据,则等待
  36. try {
  37. this.wait();
  38. } catch (InterruptedException e) {
  39. // TODO Auto-generated catch block
  40. e.printStackTrace();
  41. }
  42. }
  43. //有数据就进行处理
  44. System.out.println(this.name + "--" + this.age);
  45.  
  46. //更改标签
  47. this.flag = false;
  48. //唤醒
  49. this.notify();
  50.  
  51. }
  52. }

然后再改变生产类和消费类的代码:

生产类:

  1. public class SetThread implements Runnable {
  2. // 生产者,录入数据
  3.  
  4. private int x = 0;
  5. // 创建资源对象
  6. private Student s;
  7.  
  8. public SetThread(Student s) {
  9. this.s = s;
  10. }
  11.  
  12. public void run() {
  13. // 执行Student中的set类
  14. while (true) {
  15. if (x % 2 == 0) {
  16. s.set("张三", 23);
  17. } else {
  18. s.set("李四", 24);
  19. }
  20. x++;
  21. }
  22. }
  23.  
  24. }

消费类:

  1. public class GetThread implements Runnable {
  2. // 消费者,处理数据
  3.  
  4. // 创建资源对象
  5. private Student s;
  6.  
  7. public GetThread(Student s) {
  8. this.s = s;
  9. }
  10.  
  11. public void run() {
  12. // 执行Student类中的get方法
  13. while (true) {
  14. s.get();
  15. }
  16.  
  17. }
  18.  
  19. }

测试类不变:

  1. public class ThreadDemo {
  2.  
  3. public static void main(String[] args) {
  4.  
  5. // 创建资源对象
  6. Student s = new Student();
  7.  
  8. // 创建两个线程类的对象
  9. SetThread st = new SetThread(s);
  10. GetThread gt = new GetThread(s);
  11.  
  12. // 创建线程
  13. Thread t1 = new Thread(st);
  14. Thread t2 = new Thread(gt);
  15.  
  16. //启动线程
  17. t1.start();
  18. t2.start();
  19.  
  20. }
  21.  
  22. }

java 22 - 19 多线程之生产者和消费者的代码优化的更多相关文章

  1. java 22 - 16 多线程之生产者和消费者的问题

    生产者和消费者问题的描述图 通过上图,我们可以发现: 生产者和消费者使用的都是同一个资源(肉包子) 所以,当使用线程的时候,这两类的锁也是同一把锁(为了避免出现线程安全问题) 例子:学生信息的录入和获 ...

  2. JAVA之旅(十五)——多线程的生产者和消费者,停止线程,守护线程,线程的优先级,setPriority设置优先级,yield临时停止

    JAVA之旅(十五)--多线程的生产者和消费者,停止线程,守护线程,线程的优先级,setPriority设置优先级,yield临时停止 我们接着多线程讲 一.生产者和消费者 什么是生产者和消费者?我们 ...

  3. 母鸡下蛋实例:多线程通信生产者和消费者wait/notify和condition/await/signal条件队列

    简介 多线程通信一直是高频面试考点,有些面试官可能要求现场手写生产者/消费者代码来考察多线程的功底,今天我们以实际生活中母鸡下蛋案例用代码剖析下实现过程.母鸡在鸡窝下蛋了,叫练从鸡窝里把鸡蛋拿出来这个 ...

  4. Java:多线程之生产者与消费者

    要求:用两个线程模拟存票.售票过程.但要求每存入一张票,就售出一张票,售出后,再存入,直到售完为止. 用到的知识点:线程等待.唤醒.可能的线程中断异常 下面的方式一和方式二采用的是唤醒所有等待的线程, ...

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

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

  6. java 22 - 7 多线程之控制线程的方法

    线程休眠(让线程休息一会再运行) public static void sleep(long millis) 在自定义线程类中添加该方法. 更改后,运行测试类,结果就是每执行完一轮,就休息1秒(这里设 ...

  7. java 22 - 20 多线程之线程池

    程序启动一个新线程成本是比较高的,因为它涉及到要与操作系统进行交互. 而使用线程池可以很好的提高性能,尤其是当程序中要创建大量生存期很短的线程时,更应该考虑使用线程池. 线程池里的每一个线程代码结束后 ...

  8. java 22 - 12 多线程之解决线程安全问题的实现方式1

    从上一章知道了多线程存在着线程安全问题,那么,如何解决线程安全问题呢? 导致出现问题的原因: A:是否是多线程环境 B:是否有共享数据 C:是否有多条语句操作共享数据 上一章的程序,上面那3条都具备, ...

  9. java 22 - 9 多线程之 代码实现的方式2

    多线程的代码实现: 方式2:实现Runnable接口 步骤: A:自定义类MyRunnable实现Runnable接口 B:重写run()方法 C:创建MyRunnable类的对象 D:创建Threa ...

随机推荐

  1. 批量另存mxd

    在GIS数据处理中,批量操作是经常遇到的问题,Python脚本是解决问题的最好方法.现在需要将arcgis10.1的mxd另存为10.0,不仅数量较多,而且每个mxd要素和标注非常多,手动来操作确实慢 ...

  2. Oracle中用随机数更新字段----将一张表的数据插入另一张表----环境设置

    DECLARE CURSOR recordCursor IS SELECT longitude,latitude FROM WR_WIUST_B_SEC FOR UPDATE; recordRow r ...

  3. 在SSRS 里实现 SUMIF

    最近在做报表时,要实现Excel中的SUMIF的功能, 示例:SUMIF($B$2:$B$465,"East",$G$2:$G$465),即汇总B列值等于East的G列值. 在SS ...

  4. linux命令学习使用记录

    1.文件批量重命名:把所有.xml文件重命名.txt,第一个参数为文件名中字符串,第二个参数为替换后文件名,第三个为当前目录文件列表 rename .xml .txt *.xml 2.解压不显示过程: ...

  5. error=Error Domain=NSURLErrorDomain Code=-1003

    我的情况:模拟器 可以返回数据 .真机不可以.我手机连接的同事的共享,我以为他的网段和后台的网段在同一个网段.一直在找错误,打开手机网络设置一看  ,原来不在同一网段.手机的网络必须要跟PC的在同一个 ...

  6. Biee 11g权限详解

    前言:BIEE11g的权限较之前10g版本有了较大的变化,最明显的地方就是构架上的变化,其与 Oracle Fusion Middleware Security 紧密的集成在了一起. 在开始之前先让我 ...

  7. Mongodb Manual阅读笔记:CH9 Sharding

    9.分片(Sharding) Mongodb Manual阅读笔记:CH2 Mongodb CRUD 操作Mongodb Manual阅读笔记:CH3 数据模型(Data Models)Mongodb ...

  8. SQLServer基本函数

    1.字符串函数  长度与分析用 datalength(Char_expr) 返回字符串包含字符数,但不包含后面的空格 substring(expression,start,length) 取子串 ri ...

  9. 第二题 已知有十六支男子足球队参加2008 北京奥运会。写一个程序,把这16 支球队随机分为4 个组。采用List集合和随机数 2008 北京奥运会男足参赛国家: 科特迪瓦,阿根廷,澳大利亚,塞尔维亚,荷兰,尼日利亚、日本,美国,中国,新西 兰,巴西,比利时,韩国,喀麦隆,洪都拉斯,意大利

    package com.hanqi.test; import java.util.ArrayList; import java.util.List; import java.util.Random; ...

  10. 使用dwr时动态生成table的一个小技巧

    这篇随笔是我在07年写的,因为当时用了自己建设的blog,后来停止使用了,今天看到备份数据库还在,恢复出来放到这里.留着记录用. 我在使用DWR时,试了很多次都无法在动态生成的table中的一个或多个 ...