我看这个关于 wait,notify,sleep,join和线程同步问题 的贴子
http://blog.csdn.net/treeroot/archive/2004/11/10/175508.aspx里边有个例题,模拟了俩个人分别用洗手间的情况,其中:
第一个先刷牙,刷完后,第二个人刷,然后第一个人上厕所,完后再第一个人
就是洗手间(包括厕所功能不能同时用)我改一下,把洗手间划分为,厕所和洗漱间,一分为二,就是:
第一人刷牙的同时,第二个人上厕所,然后再交换,这里刷牙和上厕所时间是不同的但是怎么就没有第二个过程,就是第一人上厕所,第2个人刷牙
请各位大侠帮我看看到底怎么回事?非常感谢━━我修改后代码━━━━━━━━━━━━━━━━━━━━━━━━━━
class Syn
{
public static void main(String[] args) throws Exception
{
TwoPeople.ONE.start();
TwoPeople.TWO.start();
}
} class TwoPeople extends Thread{
private int i=0;
static Thread ONE=new TwoPeople(1);
static Thread TWO=new TwoPeople(2); static Object washroom=new Object();
static Object Toilet=new Toilet(); //我加的 厕所 对象
private TwoPeople(int i){this.i=i;}
public void run(){
//头:这是我修改的代码
try{
if(i==1){
synchronized(washroom){
brush();
ONE.wait();
TWO.notify();
release();
}
}else {synchronized(toilet){
release();
TWO.wait();
ONE.notify();
brush();
}
}}catch(Exception e){}
//尾:这是我修改的代码 private void brush() {
System.out.println("People "+i+" is brushing !");
try{Thread.sleep(2000);}catch(InterruptedException e){e.printStackTrace();}
//延迟两秒看效果
System.out.println("People "+i+" has burshed !");
}
private void release(){
System.out.println("People "+i+" is releasing !");
try{Thread.sleep(2000);}catch(InterruptedException e){e.printStackTrace();}
//延迟两秒看效果
System.out.println("People "+i+" has released !");
}
}━━━━━━━━━━━━━━━━━━━━━━━━━━━━
━━以下是原帖中的run方法━━━━━━━━━━━━━━━
/*
synchronized(washroom){
try{
if(i==1){
brush(); //1
washroom.wait(); //2
release(); //6
washroom.notify(); //7
}
else{
brush(); //3
washroom.notify(); //4
washroom.wait(); //5
release(); //8
}
}catch(InterruptedException e){e.printStackTrace();}
}
}*/
http://blog.csdn.net/treeroot/archive/2004/11/10/175508.aspx里边有个例题,模拟了俩个人分别用洗手间的情况,其中:
第一个先刷牙,刷完后,第二个人刷,然后第一个人上厕所,完后再第一个人
就是洗手间(包括厕所功能不能同时用)我改一下,把洗手间划分为,厕所和洗漱间,一分为二,就是:
第一人刷牙的同时,第二个人上厕所,然后再交换,这里刷牙和上厕所时间是不同的但是怎么就没有第二个过程,就是第一人上厕所,第2个人刷牙
请各位大侠帮我看看到底怎么回事?非常感谢━━我修改后代码━━━━━━━━━━━━━━━━━━━━━━━━━━
class Syn
{
public static void main(String[] args) throws Exception
{
TwoPeople.ONE.start();
TwoPeople.TWO.start();
}
} class TwoPeople extends Thread{
private int i=0;
static Thread ONE=new TwoPeople(1);
static Thread TWO=new TwoPeople(2); static Object washroom=new Object();
static Object Toilet=new Toilet(); //我加的 厕所 对象
private TwoPeople(int i){this.i=i;}
public void run(){
//头:这是我修改的代码
try{
if(i==1){
synchronized(washroom){
brush();
ONE.wait();
TWO.notify();
release();
}
}else {synchronized(toilet){
release();
TWO.wait();
ONE.notify();
brush();
}
}}catch(Exception e){}
//尾:这是我修改的代码 private void brush() {
System.out.println("People "+i+" is brushing !");
try{Thread.sleep(2000);}catch(InterruptedException e){e.printStackTrace();}
//延迟两秒看效果
System.out.println("People "+i+" has burshed !");
}
private void release(){
System.out.println("People "+i+" is releasing !");
try{Thread.sleep(2000);}catch(InterruptedException e){e.printStackTrace();}
//延迟两秒看效果
System.out.println("People "+i+" has released !");
}
}━━━━━━━━━━━━━━━━━━━━━━━━━━━━
━━以下是原帖中的run方法━━━━━━━━━━━━━━━
/*
synchronized(washroom){
try{
if(i==1){
brush(); //1
washroom.wait(); //2
release(); //6
washroom.notify(); //7
}
else{
brush(); //3
washroom.notify(); //4
washroom.wait(); //5
release(); //8
}
}catch(InterruptedException e){e.printStackTrace();}
}
}*/
━━━━━━━━━━━━━━━━━━━━━━━━━━━━
代码不用全看,关键的就是run方法里的内容我想实现的就是,
俩个人俩个线程,一个人刷牙,另个一个人同时上厕所,
牙刷完的人等上厕所,第二个人上完,第一个人就上,同时,第二个人开始刷牙
(当然刷牙所时间可能比上厕所时间长,反正就是谁先结束就先进入等待状态)听起来很简单,可是实现起来怎么那么困难呢?我昨天睡觉都在想,郁闷到吐血了我用整理以下我的run方法,思路应该很清晰吧
━━━━━━━━━━━━━━━━━━━━━━━━━━━━
if(i==1){
synchronized(washroom) {
try{
brush();
washroom.wait();
toilet.notify();
release();
}catch(InterruptedException e){e.printStackTrace();}
}
}else {
synchronized(toilet){
try{
release();
toilet.wait();
washroom.notify();
brush();
}catch(Exception e){e.printStackTrace();}
}
class Syn
{
public static void main(String[] args) throws Exception
{
TwoPeople.ONE.start();
TwoPeople.TWO.start();
}
}class TwoPeople extends Thread
{
private int i = 0;
static Thread ONE = new TwoPeople(1);
static Thread TWO = new TwoPeople(2); static Object washroom = new Object();
static Object toilet = new Object(); private TwoPeople(int i)
{
this.i = i;
} public void run()
{
try
{
if (i == 1)
{
brush();
release();
}
else
{
release();
brush();
} }
catch (Exception e)
{
e.printStackTrace();
}
} private void brush()
{
synchronized (washroom)
{
System.out.println("People " + i + " is brushing !");
try
{
Thread.sleep(1000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
System.out.println("People " + i + " has burshed !");
washroom.notify();
}
} private void release()
{
synchronized (toilet)
{
System.out.println("People " + i + " is releasing !");
try
{
Thread.sleep(2000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
System.out.println("People " + i + " has released !");
toilet.notify();
}
}
}
public static void main(String[] args) throws Exception {
TwoPeople.ONE.start();
TwoPeople.TWO.start();
}
}class Toilet {}class TwoPeople extends Thread {
private int i = 0; static Thread ONE = new TwoPeople(1); static Thread TWO = new TwoPeople(2); static Object washroom = new Object(); static Object toilet = new Toilet(); // 我加的 厕所 对象 private TwoPeople(int i) {
this.i = i;
} public void run() {
// 头:这是我修改的代码
try {
if (i == 1) {
synchronized (washroom) { //如果没人刷牙,就开始使用washroom
brush(); //刷牙
washroom.notify();//刷完牙让位,通知其它等待刷牙的人用
//TWO.notify();
}
synchronized (toilet) { //等待la'shi
release(); //lashi
toilet.notify(); //拉完了,通知其它人拉
}
}
else {
synchronized (toilet) { //如果没人拉,就开始拉,如果有人,等待
release();//开始……
toilet.notify(); //完了,好爽,通知其它等待的人 }
synchronized (washroom) { //如果没人刷牙,就开始使用washroom,如果有人就等待
brush();
washroom.notify();//刷完牙让位,通知其它等待刷牙的人用
}
}
} catch (Exception e) {
}
} // 尾:这是我修改的代码 private void brush() {
System.out.println("People " + i + " is brushing !");
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 延迟两秒看效果
System.out.println("People " + i + " has burshed !");
} private void release() {
System.out.println("People " + i + " is releasing !");
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 延迟两秒看效果
System.out.println("People " + i + " has released !");
}
}
synchronized(washroom){
brush();
ONE.wait();
TWO.notify();
release();
}
}else {synchronized(toilet){
release();
TWO.wait();
ONE.notify();
brush();
}楼主这部分代码有问题,主要是理解上的错误。既然对toilet对象上锁,就不用ONE,TWO来唤醒和释放
呵呵
package com.ttdev.tcpmonitor;import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class Syn
{
public static void main(String[] args) throws Exception
{
WashRoom room = new WashRoom();
Toilet toilet = new Toilet();
People p1 = new People(room,toilet);
People p2 = new People(room,toilet);
People p3 = new People(room,toilet);
p1.start();
p2.start();
p3.start();
}
} class People extends Thread{
private List locationList = new ArrayList();
private List queue = new ArrayList();
public void addLocation(Object location)
{
if(!locationList.contains(location))
{
locationList.add(location);
}
}
public People(WashRoom room,Toilet toilet)
{
locationList.add(room);
locationList.add(toilet);
}
private Location nextLocation()
{
int size = queue.size();
if(size == 0)
{
//重走!
queue = new ArrayList();
queue.addAll(locationList);
size = queue.size();
}
Random r = new Random();
int index = r.nextInt(size);
Location location = (Location)queue.get(index);
queue.remove(index);//
return location;
}
public void run()
{
while(true)
{
Location location = nextLocation();
synchronized(location)
{
location.toDo();
location.release();
}
}
}
}
abstract class Location
{
protected boolean inUse;
public void toDo(){};
void release(){};
} class Toilet extends Location
{
public synchronized void toDo()
{
while(inUse)
{
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName()+" is in the toilet! ");
}
public synchronized void release()
{
inUse =false;
System.out.println(Thread.currentThread().getName()+" release the Toilet !");
notifyAll();
}
}
class WashRoom extends Location
{
public synchronized void toDo()
{
while(inUse)
{
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName()+" is in the WashRoom! ");
}
public synchronized void release()
{
inUse =false;
System.out.println(Thread.currentThread().getName()+" release the WashRoom ");
notifyAll();
}
}
System.out.println(Thread.currentThread().getName()+" is in the WashRoom! ");之前要加一行:inUse=true;
还有 System.out.println(Thread.currentThread().getName()+" is in the toilet! ");之前要加一行:inUse=true;
Rayuu 的代码,没有用到wait方法,简单好多,以无刀胜有刀!强!
‘其实不用显式地notify(),系统在synchronized语句块之后会自动调用。’
这句话蛮有用的,注释掉notify,结果都一样哈。
fishyqd 代码通俗易懂,还加了注释,谢谢了
我原来可能就是要这个效果吧,我水平差,一直没写成。
Octer 一看就是世外高人呀!我俩个人都弄得焦头烂额的
代码有些地方我还得好好理解,arraylist这个类我不太熟悉原理我这样理解的:
人是个类,要去的地方是写个对象(洗漱和厕所),
要去的地方有个顺序,先去厕所还是先去洗漱,是这个意思吧?
随机生成的,这个地方,没太看明白
然后运行了,要去的地方加个锁,动作也加了个锁吧?
判断,在不在用?执行动作
最后释放锁
循环是在重走那加的吧?
运行了一下,发现,初始状态是有人已经上厕所中……
有发现,有时某人重复上厕所好多次,拉肚子了吧代码我还得理解一下再次感谢所有热心的大侠们!谢谢ps.分数怎么给,小弟分不多,平分不了哇
编写一个代码,随机一下三个数和为20 的,然后依次给吧
我这个代码太不优化了,丢人呀结果:
6 7 7
━━随机分数代码━━━━━━━━━━━━━━━━━━━━━━━━
//随机6-8之间的三个数,使其和为20
import java.util.Random;
public class Syn{
public static void main (String[] args){
Random r = new Random();
int x,y;
while (true){
x=r.nextInt(8);
y=r.nextInt(8);
if (x<6 && y<6){
x=r.nextInt(8);
y=r.nextInt(8);
//System.out.println (x+"\t"+y);
}else if ( ((20-x-y)>=6) && ((20-x-y)<=8) ){
System.out.println (x+" "+y+" "+(20-x-y));
break;
}
}
}
}
如果代码改成这样:
package com.ttdev.tcpmonitor;import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class Syn
{
public static void main(String[] args) throws Exception
{
WashRoom room = new WashRoom();
Toilet toilet = new Toilet();
People p1 = new People(room,toilet);
People p2 = new People(room,toilet);
People p3 = new People(room,toilet);
p1.start();
p2.start();
p3.start();
}
} class People extends Thread{
private List locationList = new ArrayList();
private List queue = new ArrayList();
public synchronized void addLocation(Object location)
{
if(!locationList.contains(location))
{
locationList.add(location);
}
}
public People(WashRoom room,Toilet toilet)
{
addLocation(room);
addLocation(toilet);
}
private Location nextLocation()
{
int size = queue.size();
if(size == 0)
{
//拉肚子了,同时该人有洁癖,继续上厕所,洗漱!
queue = new ArrayList();
queue.addAll(locationList);
size = queue.size();
}
Location location = (Location)queue.get(0);
queue.remove(0);
return location;
}
public void run()
{
while(true)
{
Location location = nextLocation();
//synchronized(location) // discard this line for testing the multi-threads communication
{
location.toDo();
//location.release();
}
}
}
}
abstract class Location
{
protected boolean inUse;
public void toDo(){};
void release(){};
} class Toilet extends Location
{
public synchronized void toDo()
{
while(inUse)
{
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
inUse =true;
System.out.println(Thread.currentThread().getName()+" is in the toilet! ");
release();
}
public void release()
{
inUse =false;
System.out.println(Thread.currentThread().getName()+" release the Toilet !");
notifyAll();
}
public String toString()
{
return "Toilet:"+this.hashCode();
}
}
class WashRoom extends Location
{
public synchronized void toDo()
{
while(inUse)
{
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
inUse =true;
System.out.println(Thread.currentThread().getName()+" is in the WashRoom! ");
release();
}
public synchronized void release()
{
inUse =false;
System.out.println(Thread.currentThread().getName()+" release the WashRoom ");
notifyAll();
}
public String toString()
{
return "WashRoom:"+this.hashCode();
}
}