1 需求

资源有姓名和性别。

两个线程,
    一个负责给姓名和性别赋值,
    一个负责获取姓名和性别的值。

要求1,运行一下,解决程序的 "妖"的问题。

要求2,实现正确数据的间隔输出 如
张飞--男
rose--女女女
张飞--男
rose--女女女

要求3,对代码进行重构。
    将name,sex私有化,资源类提供对其访问的方法。

要求4,将程序改成JDK1.5的Lock Condition接口。

-------------------------------------

2 妖的出现和解决

原代码:

//描述资源。
class Resource
{
String name;
String sex;
}
//赋值线程任务
class Input implements Runnable
{
private Resource r;
// private Object obj = new Object();
Input(Resource r)//任务一初始化就必须有要处理的资源。
{
this.r = r;
}
public void run()
{
int x = 0;
while(true)
{
{
if(x==0)
{
r.name = "张飞";
r.sex = "男";
}
else
{
r.name = "rose";
r.sex = "女女女女";
}
}
x = (x+1)%2;//实现切换。
}
}
}
//获取值线程任务
class Output implements Runnable
{
private Resource r ;
// private Object obj = new Object();
Output(Resource r)
{
this.r = r;
}
public void run()
{
while(true)
{ System.out.println(r.name+"....."+r.sex);
}
}
} class ThreadTest2
{
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(); }
}

 测试结果: 会出现张飞.....女.或者是rose.....男,

分析原因:假如某个时刻,name=rose,sex=女,进入if中,进行了name=张三后就停止了,不进行了sex的赋值,进入打印,这是时的name=张三,sex=女;

解决方法:出现了安全问题.需要加入同步.详情请点击,

//描述资源。
class Resource
{
String name;
String sex;
}
//赋值线程任务
class Input implements Runnable
{
private Resource r;
// private Object obj = new Object();
Input(Resource r)//任务一初始化就必须有要处理的资源。
{
this.r = r;
}
public void run()
{
int x = 0;
while(true)
{
synchronized(r) //加入同步
{
if(x==0)
{
r.name = "张飞";
r.sex = "男";
}
else
{
r.name = "rose";
r.sex = "女女女女";
}
}
x = (x+1)%2;//实现切换。
}
}
}
//获取值线程任务
class Output implements Runnable
{
private Resource r ;
// private Object obj = new Object();
Output(Resource r)
{
this.r = r;
}
public void run()
{
while(true)
{
synchronized(r) //加入同步
{
System.out.println(r.name+"....."+r.sex);
}
}
}
} class ThreadTest2
{
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(); }
}

测试结果

-------------------------------------

3 等待唤醒

出现问题:由上面的结果可知,出现了大量的男或女,没有出现一男一女

解决问题:加入等待唤醒.输入后等待,唤醒输出,输出后,唤醒输入;一般要加入个标志

//描述资源。
class Resource
{
String name;
String sex;
//定义标记,
boolean flag = false; }
//赋值线程任务
class Input implements Runnable
{
private Resource r;
// private Object obj = new Object();
Input(Resource r)//任务一初始化就必须有要处理的资源。
{
this.r = r;
}
public void run()
{
int x = 0;
while(true)
{
synchronized(r)
{
if(r.flag)
try{r.wait();}catch(InterruptedException e){}//等待唤醒机制
if(x==0)
{
r.name = "张飞";
r.sex = "男";
}
else
{
r.name = "rose";
r.sex = "女女女女";
} r.flag = true;
r.notify(); //等待唤醒机制
}
x = (x+1)%2;//实现切换。
}
}
}
//获取值线程任务
class Output implements Runnable
{
private Resource r ;
// private Object obj = new Object();
Output(Resource r)
{
this.r = r;
}
public void run()
{
while(true)
{
synchronized(r)
{
if(!r.flag)//等待唤醒机制
try{r.wait();}catch(InterruptedException e){}
System.out.println(r.name+"....."+r.sex);
r.flag = false;
r.notify();//等待唤醒机制
}
}
}
} class ThreadTest2_2
{
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(); }
}

测试结果

-------------------------------------

 4 代码重构

解决问题:将name,sex私有化,资源类提供对其访问的方法。这时加同步要放在共有资源里面

//描述资源。
class Resource
{
private String name; //
private String sex; //代码重构
//定义标记,
private boolean flag = false; //赋值功能。
public synchronized void set(String name,String sex)// //代码重构
{
if(flag)
try{this.wait();}catch(InterruptedException e){}
this.name = name;
this.sex = sex;
flag = true;
this.notify();
} //获取值。
public synchronized void out()
{
if(!flag)
try{this.wait();}catch(InterruptedException e){}
System.out.println(name+"------"+sex);
flag = false;
this.notify();
} }
//赋值线程任务
class Input implements Runnable
{
private Resource r;
Input(Resource r)//任务一初始化就必须有要处理的资源。
{
this.r = r;
}
public void run()
{
int x = 0;
while(true)
{
if(x==0)
{
r.set("张飞","男");
}
else
{
r.set("rose","女女女女");
}
x = (x+1)%2;//实现切换。
}
}
}
//获取值线程任务
class Output implements Runnable
{
private Resource r ;
Output(Resource r)
{
this.r = r;
}
public void run()
{
while(true)
{
r.out();
}
}
} class ThreadTest2_3
{
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(); }
}

-------------------------------------

5,将程序改成JDK1.5的Lock Condition接口

解决问题:Lock替换了 同步函数或者同步代码块。Condition替代了 监视器方法,将监视器方法从锁上分离出来,单独封装成Condition对象。

import java.util.concurrent.locks.*;
//描述资源。
class Resource
{
private String name;
private String sex; //程序改成JDK1.5的Lock Condition接口
//定义标记,
private boolean flag = false; //先创建锁对象。
private final Lock lock = new ReentrantLock();// //通过锁对象获取监视器对象。
private Condition con = lock.newCondition();// //赋值功能。
public void set(String name,String sex)
{
lock.lock();//
try{
if(flag)
try{con.await();}catch(InterruptedException e){}//
this.name = name;
this.sex = sex;
flag = true;
con.signal();//
}finally{
lock.unlock();//
}
} //获取值。
public void out()
{
lock.lock();//
try{
if(!flag)
try{con.await();}catch(InterruptedException e){}//
System.out.println(name+"------"+sex);
flag = false;
con.signal();//
}finally{
lock.unlock();//
}
} }
//赋值线程任务
class Input implements Runnable
{
private Resource r;
Input(Resource r)//任务一初始化就必须有要处理的资源。
{
this.r = r;
}
public void run()
{
int x = 0;
while(true)
{
if(x==0)
{
r.set("张飞","男");
}
else
{
r.set("rose","女女女女");
}
x = (x+1)%2;//实现切换。
}
}
}
//获取值线程任务
class Output implements Runnable
{
private Resource r ;
Output(Resource r)
{
this.r = r;
}
public void run()
{
while(true)
{
r.out();
}
}
} class ThreadTest2_4
{
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(); }
}

多线程的练习----妖,等待唤醒,代码重构,lock到condition的更多相关文章

  1. java-多线程的练习----妖,等待唤醒,代码重构,lock到condition

    1 需求 资源有姓名和性别. 两个线程,    一个负责给姓名和性别赋值,    一个负责获取姓名和性别的值. 要求1,运行一下,解决程序的 "妖"的问题. 要求2,实现正确数据的 ...

  2. 多线程之间的通信(等待唤醒机制、Lock 及其它线程的方法)

    一.多线程之间的通信. 就是多个线程在操作同一份数据, 但是操作的方法不同. 如: 对于同一个存储块,其中有两个存储位:name   sex, 现有两个线程,一个向其中存放数据,一个打印其中的数据. ...

  3. Android-Java多线程通讯(生产者 消费者)&等待唤醒机制

    多线程通讯:例如:有一个线程任务在run生产,还有一个线程任务在run消费: VIP尊贵的身份,生产者 消费者 方式,(精心生产制作一个超级无敌好吃的面包,卖给VIP尊贵的身份消费者)生产与消费 一对 ...

  4. Android-Java多线程通讯(生产者 消费者)&10条线程对-等待唤醒/机制的管理

    上一篇博客 Android-Java多线程通讯(生产者 消费者)&等待唤醒机制 是两条线程(Thread-0 / Thread-1) 在被CPU随机切换执行: 而今天这篇博客是,在上一篇博客A ...

  5. java多线程中的生产者与消费者之等待唤醒机制@Version1.0

    一.生产者消费者模式的学生类成员变量生产与消费demo,第一版1.等待唤醒:    Object类中提供了三个方法:    wait():等待    notify():唤醒单个线程    notify ...

  6. java基础知识回顾之java Thread类学习(八)--java多线程通信等待唤醒机制经典应用(生产者消费者)

     *java多线程--等待唤醒机制:经典的体现"生产者和消费者模型 *对于此模型,应该明确以下几点: *1.生产者仅仅在仓库未满的时候生产,仓库满了则停止生产. *2.消费者仅仅在有产品的时 ...

  7. JAVA之旅(十四)——静态同步函数的锁是class对象,多线程的单例设计模式,死锁,线程中的通讯以及通讯所带来的安全隐患,等待唤醒机制

    JAVA之旅(十四)--静态同步函数的锁是class对象,多线程的单例设计模式,死锁,线程中的通讯以及通讯所带来的安全隐患,等待唤醒机制 JAVA之旅,一路有你,加油! 一.静态同步函数的锁是clas ...

  8. Java多线程02(线程安全、线程同步、等待唤醒机制)

    Java多线程2(线程安全.线程同步.等待唤醒机制.单例设计模式) 1.线程安全 如果有多个线程在同时运行,而这些线程可能会同时运行这段代码.程序每次运行结果和单线程运行的结果是一样的,而且其他的变量 ...

  9. Java多线程(二)同步与等待唤醒

     1:数据安全问题 1.1:什么情况下会出现数据安全问题? 多个线程对同一个资源进行操作,并且操作资源的语句有多条.那么这个时候这些语句因为cpu的随机性,有可能被多个线程分开执行.导致数据安全问题. ...

随机推荐

  1. DIV+CSS规范命名大全集合

    (从已经死了一次又一次终于挂掉的百度空间人工抢救出来的,发表日期 2014-06-19)   网页制作中规范使用DIV+CSS命名规则,可以改善优化功效特别是团队合作时候可以提供合作制作效率,具体DI ...

  2. 如何提高数据库update更新的速度

    不用不知道,一用吓一跳..看下面这条SQL语句 String sql="update cats set name_alias='"+rs.getString(1)+"'w ...

  3. TCP具体解释(2):三次握手与四次挥手

    TCP(Transmission Control Protocol,传输控制协议)是基于连接的协议,也就是说,在正式收发数据前,必须和对方建立可靠的连接,就好像你给别人打电话.必须等线路接通了.对方拿 ...

  4. 在Android应用中实现Google搜索的例子

    有一个很简单的方法在你的 Android 应用中实现 Google 搜索.在这个例子中,我们将接受用户的输入作为搜索词,我们将使用到 Intent.ACTION_WEB_SEARCH . Google ...

  5. Android Compatibility package 兼容性开发套件

    我们认为Android 3.0平板电脑操作系统在美国时间2011年2月22日的正式推出,对于Android手机应用程序开发者所象征的意涵是: 之前大家所开发过的Android手机应用,除了可以在And ...

  6. UVA 1484 - Alice and Bob's Trip(树形DP)

    题目链接:1484 - Alice and Bob's Trip 题意:BOB和ALICE这对狗男女在一颗树上走,BOB先走,BOB要尽量使得总路径权和大,ALICE要小,可是有个条件,就是路径权值总 ...

  7. Ajax缓存解决办法

    解决办法有如下几种:       1.在服务端加 header("Cache-Control: no-cache, must-revalidate");(如php中) 2.在aja ...

  8. $.getJSON()方法的 callback说明

    $.getJSON()方法跨域 去取得服务器的json对象的时候,url的后缀最后带一个"callback=?"的参数作为成功的回调函数:如: var url = "${ ...

  9. C# 之 读写文件

    1.使用 FileStream 读写文件 添加命名空间引用: using System; using System.Collections.Generic; using System.Text; us ...

  10. JS Math算数

    Math.ceil()ceil() 方法可对一个数进行上舍入. ceil英译 天花板 参数必须是一个数值.返回值大于等于 x,并且与它最接近的整数. Math.floor()floor() 方法可对一 ...