多线程初探(八)
2016-01-19 17:08
176 查看
package com.liujunhua.ith02; /** * 线程的等待唤醒机制 * 两个线程对同一资源进行操作,为保证两者操作资源的独立性,出现了等待唤醒机制。 * 1.Input线程负责对变量赋值,为了避免在Input在具有CPU执行权时,进行重复的变量赋值动作, * 当首次赋值后进行标记,当线程再次赋值的时候,先对标记进行判断,若已经赋值并且该数值还没有 * 被Output输出,Input线程就等待。即放弃执行权。 * 2.当Input等待的时候Output就会获得CPU执行权,就会执行相应的输出操作。当完成输出操作后,它将标记为已经操作状态。 * 当下次执行的时候,如果发现标记已经输出,并且Input没有进行新的赋值,那么就会进入等待状态。 * * 从而实现了等待唤醒机制。 * * wait(); * notify(); * notifyAll(); * * 这些方法都使用在同步中,因为要对持有监视器(锁)的线程进行操作。 * 所以要使用在同步中,因为只有同步才具有锁。 * * 但是为什么这些操作线程的方法要定义在Object类中呢? * * 那是因为这些方法在操作同步中的线程是,都必须要标识他们所操作线程的锁, * 只有同一个锁上的被等待的线程,可以被同一个锁上的notify唤醒。 * * 也就是说,等待和唤醒必须是同一个锁。 * * 而锁可以是任意对象,所以可以被任意对象调用的方法定义在object类中。 */ public class Demo01 { public static void main(String[] args){ Res r = new Res(); Input in = new Input(r); Output out = new Output(r); Thread t1 = new Thread(in); Thread t2 = new Thread(out); t1.start(); t2.start(); } } class Res { private String name; private String sex; private boolean flag = false; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public boolean isFlag() { return flag; } public void setFlag(boolean flag) { this.flag = flag; } public void print(){ System.out.println(this.name+"........"+this.sex); } } /** * 这里线程锁的创建很有技巧性,如果仅仅是简单的obj对象,肯定是不行的,因为一个obj不可能在两个类里面都可以用。 * 但此时又需要两个同步代码块用同一个线程锁,这里便采用了两个线程共同操作的Res对象作为线程锁,很好的解决了线程的安全问题。 */ class Input implements Runnable { private Res r; Input(Res r) { this.r = r; } @Override public void run() { // TODO Auto-generated method stub int mark = 0; while (true) { synchronized (r) { if(r.isFlag()) try { r.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } if (mark == 0) { r.setName("mike"); r.setSex("man"); } else { r.setName("丽丽"); r.setSex("女女"); } mark = (mark + 1) % 2; r.setFlag(true); r.notify(); } } } } class Output implements Runnable { private Res r; Output(Res r) { this.r = r; } @Override public void run() { // TODO Auto-generated method stub while (true) { synchronized (r) { if(!r.isFlag()){ try { r.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } r.print(); r.setFlag(false); r.notify(); } } } }
相关文章推荐
- 写给开发者:记录日志的10个建议
- Java内存模型FAQ(十)volatile是干什么用的
- Redis-3.0.6 集群部署集成SpringJava工程-----spring集成
- 详解在C++中显式默认设置的函数和已删除的函数的方法
- RecyclerView match_parent 不起作用的解决方法
- 2016-1-19(移动触摸事件以及事件的一些属性引申)
- 关于java hashmap的心得
- Java NIO概述
- poj1185炮兵阵地
- android自定义控件的最大高度MaxHeightView
- Hadoop伪分布式搭建-(1)
- iOS学习——利用Timer更新通话时间与播放器进度条
- auto_ptr应用
- 缓存工具类封装
- infix 自定义运算符
- AutoLayout小技巧系列(二)
- Objective-C的hook方案(一): Method Swizzling
- Java内存模型FAQ(九)在新的Java内存模型中,final字段是如何工作的
- windows线程yield以及Sleep(0)和SwitchToThread之间的区别
- Java 浅析I/O模型