- 浏览: 1588886 次
- 来自: 上海
文章分类
- 全部博客 (374)
- Java (101)
- Struts (54)
- Oracle (30)
- JavaScript (16)
- Spring (27)
- Hibernate (16)
- MyEclipse (3)
- JSF (1)
- FreeMarker (2)
- SiteMesh (2)
- JfreeChart (2)
- Ibatis (2)
- JSP (12)
- MyBatis (4)
- SWFupload (1)
- EJB (4)
- Jboss (4)
- WebService (2)
- Linux (16)
- Android (2)
- XML (6)
- Java 网络编程 (13)
- AXIS2 (1)
- FTP (1)
- Jswing (1)
- Socket (3)
- 杂文选集 (6)
- solr (2)
- PS (1)
- Tomcat (7)
- JDBC (9)
- Highcharts (1)
- maven (1)
- Nodejs (0)
- navicat (2)
- Exception (5)
- eclipse (3)
- jQuery (1)
- springMVC (4)
- MySQL (11)
- SVN (1)
- Sql Server (1)
- zookeeper (1)
- JVM (1)
- Groovy (2)
- Git (1)
- Nginx (1)
- DynamicReport (1)
- IDEA (2)
- JasperReports (1)
- Postgresql (2)
- Mac (1)
- gradle (1)
- 数据结构算法 (1)
最新评论
-
hpu145:
引用引用
java 千分位的添加和去除 -
被遗忘的下路:
少了个junit-4.8.2的包
SSH2整合完整案例(四十三) -
白天看黑夜:
java过滤emoji字符处理,希望能帮到你http://ww ...
emoji 表情图片解决方法 -
caipeiming:
这个挺好JavaScript实现input输入框控件只允许输入 ...
js 控制文本框只能输入中文、英文、数字等 -
双子树:
东西太好啦受教啊
Struts2 JSP中将list,set ,Map传递到Action然后<s:iterator>遍历(三十五)
线程间通信问题
优化上面的 等待唤醒机制
线程间通信 ,生产者 和消费者
使用 JDK1.5的新特性 来优化上面的代码
/** * 线程间通信问题 * 其实就是多个线程在操作通过一个资源,但是操作的动作不同. * * 同步的前提: * 1.必须要有两个或者两个以上的线程 * 2.必须是多个线程使用同一个锁 * * 等待唤醒机制 * * wait() * notify() * notifyAll(); * * 都使用在同步中,因为要对持有监视器的线程操作,所以要使用在 同步中,因为只有 同步才具有锁. * * 为什么这些操作线程的方法要定义在Object类中呢? * 因为 这些方法 在操作同步中线程时,都必须要表示他们所操作线程的只有的锁. * 只有 同一个锁上的 被等待线程,可以被同一个锁上的notify唤醒 * 不可以对不同锁中的线程进行唤醒. * * 也就是,等待和唤醒 必须是同一个锁 * 而锁可以是任意对象,所以可以被任意对象调用的 方法定义在 Object中 * * * */ class Resource{ String name; String sex; boolean flag=false; //表示没有值 } //复制 class Input implements Runnable{ Resource r; Input(Resource r){ this.r=r; } //Object obj=new Object(); public void run(){ int x=0; while(true){ synchronized(r){ //obj -->this--> input.class(Output.class,InputOutputDemo.class)-->r if(r.flag){ try { r.wait(); //线程运行的时候,程序会在内存中创建线程池,等待的线程会存在线程中 } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } if(x==0){ r.name="mike"; r.sex="man"; }else{ r.name="丽丽"; r.sex="女女女女"; } r.flag=true; r.notify();//唤醒 输出线程 通常会唤醒 线程池中 第一被等待的线程 } x=(x+1)%2; } } } //取出后 然后输出 class Output implements Runnable{ Resource r; Output(Resource r){ this.r=r; } //Object obj=new Object(); public void run(){ while(true){ synchronized(r){ //obj -->this--> input.class(Output.class,InputOutputDemo.class)-->r if(!r.flag) try { r.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(r.name+"--------------"+r.sex); r.flag=false; r.notify(); } } } } public class InputOutputDemo { public static void main(String[] args) { Resource r=new Resource(); Input in=new Input(r); Output out=new Output(r); Thread t1=new Thread(in); Thread t2=new Thread(out); t1.start(); t2.start(); } }
优化上面的 等待唤醒机制
/** * 线程间通信问题 * 其实就是多个线程在操作通过一个资源,但是操作的动作不同. * * 同步的前提: * 1.必须要有两个或者两个以上的线程 * 2.必须是多个线程使用同一个锁 * * 等待唤醒机制 * * 对上面的程序进行优化 */ class Resource{ private String name; private String sex; private boolean flag=false; //表示没有值 public synchronized void setValue(String name,String sex){ if(flag){ try{ this.wait(); //线程运行的时候,程序会在内存中创建线程池,等待的线程会存在线程中 } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } this.name=name; this.sex=sex; flag=true; this.notify(); } public synchronized void out(){ if(!flag){ try{ this.wait(); //线程运行的时候,程序会在内存中创建线程池,等待的线程会存在线程中 } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } System.out.println(name+"--------------"+sex); flag=false; this.notify(); } } class Input implements Runnable{ Resource r; Input(Resource r){ this.r=r; } //Object obj=new Object(); public void run(){ int x=0; while(true){ if(x==0){ r.setValue("mike", "man"); }else{ r.setValue("莉莉", "女女"); } x=(x+1)%2; } } } //取出后 然后输出 class Output implements Runnable{ Resource r; Output(Resource r){ this.r=r; } //Object obj=new Object(); public void run(){ while(true){ r.out(); } } } public class InputOutputDemo { public static void main(String[] args) { Resource r=new Resource(); new Thread(new Input(r)).start(); new Thread(new Output(r)).start(); /*Input in=new Input(r); Output out=new Output(r); Thread t1=new Thread(in); Thread t2=new Thread(out); t1.start(); t2.start();*/ } }
线程间通信 ,生产者 和消费者
/** 线程间通信 ,生产者 和消费者 * * 发现 上面的 等待唤醒机制 中 如果 线程数 超过过两个 使用 notify 就有问题了 * 原因 就是 当一个线程等待后 被其他线程 唤醒 就不会判断 flag 为真 为假 ,这样就会在某一时间段就会 生产多个商品 或者 消费多个商品 * */ class Resouce{ private String name; private int count=1; private boolean flag=false; // while(true){ //t1 t3 循环一次后发现 不一定 public synchronized void setValue(String name){ while(flag) try { this.wait(); } catch (InterruptedException e) {// t1 (1等待--->5运行 ) t3 (2等待 --6 运行) // TODO Auto-generated catch block e.printStackTrace(); } this.name=name+"...."+count++; System.out.println(Thread.currentThread().getName()+"....生产者...."+this.name); flag=true; //this.notify() // 只唤醒线程中 最先等待那一个线程 this.notifyAll(); } //} public synchronized void out(){ while(!flag) try { this.wait();// t1 (3等待) t3 (4等待) } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"...........消费者............."+this.name); flag=false; this.notifyAll(); } } class Producer implements Runnable{ Resouce r; Producer(Resouce r){ this.r=r; } public void run(){ while(true){ r.setValue("+商品+"); } } } class Consumer implements Runnable{ Resouce r; Consumer(Resouce r){ this.r=r; } public void run(){ while(true){ r.out(); } } } public class ProducerConsumerDemo { public static void main(String[] args) { // TODO Auto-generated method stub Resouce r=new Resouce(); Producer p=new Producer(r); Consumer c=new Consumer(r); Thread t1=new Thread(p); Thread t2=new Thread(c); //使用 两个线程的时候 仿照 之前的 例子是没有问题,如果 超过两个线程后就会有问题了 Thread t3=new Thread(p); Thread t4=new Thread(c); t1.start(); t2.start(); // 因此 使用上 了 while notifyAll 才解决这个问题 这是JDK1.5之前 的程序都这么干的 t3.start(); t4.start(); }
使用 JDK1.5的新特性 来优化上面的代码
import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** * JDK5.0 中提供了 多线程 升级解决方案 * 将同步Synchronized 替换成 显示的 Lock机制 * 将 Object 中的 wait notify notifyall 替换成了 Condition对象中 await signal signalAll * * Condition 对象可以用 Lock 锁,进行获取 * * 在该实例中 实现了本方 只唤醒 对方的操作 * */ class Resouce{ private String name; private int count=1; private boolean flag=false; private Lock lock=new ReentrantLock(); private Condition c_proc=lock.newCondition(); //声明 一个锁中 监视器对象 private Condition c_cons=lock.newCondition(); //声明 一个锁中 监视器对象 public void setValue(String name) throws InterruptedException{ lock.lock(); //synchronized try{ while(flag) c_proc.await(); //this.wait() this.name=name+"...."+count++; System.out.println(Thread.currentThread().getName()+"....生产者...."+this.name); flag=true; }finally{ //释放锁的动作一定要执行 //this.notify() // 只唤醒线程中 最先等待那一个线程 //this.notifyAll(); c_cons.signal(); //只需要唤醒 消费者中的一个就可以了 不需要 All } } public void out() throws InterruptedException{ lock.lock(); //synchronized 一看就知道是同一个锁 是吧 呵呵 try{ while(!flag) c_cons.await(); // this.wait(); System.out.println(Thread.currentThread().getName()+"...........消费者............."+this.name); flag=false; }finally{ //this.notifyAll(); c_proc.signal(); // 唤醒生产者中的一个就可以了 } } } //生产者 class Producer implements Runnable{ Resouce r; Producer(Resouce r){ this.r=r; } public void run(){ while(true){ try { r.setValue("+商品+"); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } //消费者 class Consumer implements Runnable{ Resouce r; Consumer(Resouce r){ this.r=r; } public void run(){ while(true){ try { r.out(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } public class ProducerConsumerDemo { public static void main(String[] args) { // TODO Auto-generated method stub Resouce r=new Resouce(); Producer p=new Producer(r); Consumer c=new Consumer(r); Thread t1=new Thread(p); Thread t2=new Thread(c); Thread t3=new Thread(p); Thread t4=new Thread(c); t1.start(); t2.start(); t3.start(); t4.start(); } }
发表评论
-
检测一个字符串是否在jvm的常量池中
2018-12-18 17:34 995public static boolean inPool( ... -
UTC时间, GMT时间 ,夏令时
2017-08-18 15:12 2280经常混淆于此,特地研究了一下,记录在此以备忘。 整个地 ... -
java 反射List
2017-02-18 01:58 5650package com.enhance.reflect; ... -
JDK1.5 Exchange 两个线程互换数据
2016-08-04 18:00 980import java.util.concurrent ... -
JDK1.5 CountDownLatch
2016-08-04 16:25 1054/* * 还有一个利用场景: ... -
java CyclicBarrier 循环障碍阻塞
2016-08-03 23:54 1005//一个同步辅助类,它允许一组线程互相等待,直到到达某个公 ... -
java 信号灯 Semaphore
2016-08-03 23:53 1822更多介绍http://blog.csdn.net/java20 ... -
java 使用读写锁设计一个缓存模型
2016-08-03 23:49 1416import java.util.HashMap; ... -
java 读写锁
2016-08-03 23:46 813import java.util.Random; i ... -
java 多个线程之间同步通信
2016-08-02 17:16 2396import java.util.concurrent ... -
jdk1.5 锁 Lock 和 Condition
2016-08-02 17:03 922// lock 练习 public class Lock ... -
JDK1.5 获取线程执行结果 Callable Future
2016-08-02 15:08 1171import java.util.Random; i ... -
JDK1.5 线程池
2016-08-02 14:48 800import java.util.concurrent ... -
java 多线程ThreadLocal
2016-08-02 00:13 1144import java.util.Random; ... -
java 定时器 Timer
2016-08-01 16:53 3890import java.util.Calendar; ... -
java 多线程同步+通信
2016-08-01 16:48 964/** *父子线程 交替打印10 次, 100次 ... -
java 线程同步
2016-08-01 16:43 1020import java.util.concurrent.l ... -
java多线程练习
2016-08-01 16:35 1838Java 传统多线程 Java 多线程同步 Java 多线 ... -
java 传统多线程
2016-08-01 16:34 1001/** * 传统多线程 */ public ... -
java 图片,剪切,缩放
2016-01-06 10:21 2228package out; import ja ...
相关推荐
【JAVA12天全掌握】课程旨在帮助学员在12天内系统地理解和掌握Java编程语言的核心概念和技术。这不仅是一场快速学习的挑战,也是一个深度理解Java编程基础的全面之旅。通过本课程,学员将从零开始,逐步建立起扎实的...
第12天:字符串王者地位 第13天:算法工具类包装类 第14天:正则及其他类 第15-18天:数组到集合 第19天:文件操作IO 第20、21天:IO流文件操作类图 第22天:其他流 第23天:多线程 第24天:多线程深入 第25天:GUI ...
本文介绍了如何使用Java Swing GUI框架、多线程以及日期时间处理技术来实现一个简单的多线程倒计时器。通过这个例子,读者可以了解到如何在Java中构建GUI应用程序,如何利用多线程来实现后台任务的并发执行,以及...
6. **多线程**:Java对多线程的支持非常强大,你需要学习如何创建和管理线程,理解同步与互斥,以及线程池的概念,这对提升程序性能有很大帮助。 7. **网络编程**:Java的Socket编程能让你构建网络应用程序,理解...
12. **反射**:通过反射机制,可以在运行时动态地获取类的信息并操作对象,这是Java高级特性之一。 13. **泛型**:泛型提供了一种在编译时检查类型安全的方法,同时允许程序员编写更灵活的代码。 14. **Java API的...
标题中的“初学Java时花费12天做的一款小游戏”表明这是一个初级Java程序员为了学习和实践编程技能而创建的小型游戏项目。这个项目可能包含了基本的编程概念、面向对象设计原则以及简单的游戏逻辑。在12天的时间内,...
Java入门第一课主要针对初学者,...此外,随着课程的深入,可能还会涉及到更多高级主题,如集合框架、多线程、网络编程等。对于持续更新的课程,可能还会有新的特性和实践案例添加进来,以保持内容的时效性和实用性。
1. **时间处理类**: Java中的`java.time`包提供了处理时间的类,如`LocalTime`,它是用来表示一天中的时间(小时、分钟、秒、纳秒)。在这个数字时钟程序中,`LocalTime.now()`可能被用来获取当前时间。 2. **24...
7. **多线程编程**:了解线程的概念,学习Thread类和Runnable接口,掌握同步和异步操作,以及线程间的通信。 8. **JAVA Swing和JavaFX**:学习如何使用JAVA创建图形用户界面(GUI),掌握Swing组件库的使用,或者更...
《21天学通Java》是一本面向初学者的编程教程,旨在帮助读者在短时间内掌握Java编程基础。这本书由庞永庆、庞丽娟等人编著,提供了丰富的实例和实践练习,以帮助学习者深入理解Java语言的核心概念。源代码是书中各个...
6. **多线程**:Java提供了对多线程的支持,理解线程的创建、同步和通信,可以实现高效的并发处理。 7. **反射机制**:反射是Java的一大特色,它允许在运行时检查类、接口、字段和方法的信息,甚至动态调用方法。 ...
6. **多线程**:Java内置了对多线程的支持,包括Thread类、Runnable接口,以及同步控制方法(如synchronized关键字、wait()、notify()和notifyAll())。 7. **反射API**:Java反射机制允许在运行时动态地获取类的...
多线程编程是Java的一个重要特性,通过实现Runnable接口或继承Thread类创建线程。了解并发控制(synchronized关键字、wait/notify机制)、线程状态以及线程池的概念。 9. **文件与文件系统** 学习File类用于文件...
总之,本Java视频教程结合黑马Java零基础辅导班的12天课件和源码,为初学者提供了一个系统学习Java的平台。通过深入学习和实践,你将能掌握Java编程的基本技能,为进一步深入学习Java的高级特性和框架打下坚实基础。
9. **多线程**:Java内置了对多线程的支持,你可以通过实现Runnable接口或继承Thread类来创建线程。 10. **Swing和JavaFX**:对于图形用户界面(GUI)开发,Java提供了Swing和JavaFX库。这两个库包含了各种组件和...
9. **多线程**:Java内置了对多线程的支持,学习者需要理解线程的创建、同步、生命周期管理等概念。 10. **文件和目录操作**:Java提供了File类来处理文件和目录,包括创建、删除、重命名等操作。 11. **Swing和...
11. **多线程**:Java内置了多线程支持,通过Thread类或实现Runnable接口创建并管理线程,实现并发执行。 12. **Swing与JavaFX**:Java提供GUI(图形用户界面)工具包,如Swing和JavaFX,用于构建桌面应用。 13. *...
9. **多线程**:Java支持多线程编程,通过Thread类和Runnable接口可以创建并管理多个执行线程,提高程序的并发性能。 10. **Java Swing和JavaFX**:这两是Java的图形用户界面(GUI)库,用于构建桌面应用程序。...
10. **多线程**:Java内置了对多线程的支持,通过实现Runnable接口或继承Thread类来创建线程。了解线程的同步和通信机制,如synchronized关键字、wait()、notify()和notifyAll()方法。 11. **文件和目录操作**:...