需求:生产一个馒头,然后消费者就吃掉一个馒头;在两个线程间徘徊;不能用同步函数,要用同步代码块;
下面一段代码是用同步函数写的,后面用同步代码块一直没有成功;还请指教,谢谢;
public static void main(String[] args)throws Exception{
Rescoss R=new Rescoss();
producter P=new producter(R);
Eater E=new Eater(R);
Thread t1=new Thread(P);
Thread t2=new Thread(E);
Thread t3=new Thread(P);
Thread t4=new Thread(E);
t1.setDaemon(true);
t2.setDaemon(true);
t3.setDaemon(true);
t4.setDaemon(true);
t1.start();
t2.start();
t3.start();
t4.start();
for(int i=0;i<35;i++){
System.out.println(Thread.currentThread().getName()+".."+i);
Thread.sleep(200);
}
}
}
class Rescoss{ //生产者和消费者会进行操作的一个资源;好比一个盘子;这只是一个盘子,它的功能就是装东西;
String name;// 在这个盘子里面装的东西的名字;、
double count;//给每一个生产出来的产品起一个名字;
boolean flag; //初始化的boolean的值是假;
public synchronized void set(String name){//生产出产品;(这个资源有被生产的功能)
while(flag){ //用的是while循环判断而不是if,这样的话,每一次获取锁的线程都要重新来判断;不会出现重复拿着锁的情况发生;
try{
this.wait(); //如果是假,那么进入等待状态;
}catch(InterruptedException e){
e.printStackTrace();
}
}
this.name=name+count;
count++;
try{Thread.sleep(200);}catch(InterruptedException e){} //休眠都是需要进行try{}catch(){}的判断;
System.out.println(Thread.currentThread().getName()+"生产者..."+this.name);
flag=true; //将参数手动变成真,这样的话就可以由生产的线程进入消费的线程,在这两个线程间来回;
this.notifyAll(); //最后唤醒,这里用的不是单独唤醒,而是唤醒全部的全线程,这样的话,就和最开始的while进行连接;
//System.out.println(Thread.currentThread().getName()+"生产者..."+this.name);
}
public synchronized void get(){//你生产出一个产品,我就消费一个产品; 用的是同步函数而不是同步代码块; (这个资源有被消费的功能)
//System.out.println(Thread.currentThread().getName()+"消费者////"+this.name);
while(!flag){
try{
this.wait();
}catch(InterruptedException e){
e.printStackTrace();
}
try{Thread.sleep(200);}catch(InterruptedException e){}
}
System.out.println(Thread.currentThread().getName()+"消费者..."+this.name);
flag=false;
this.notifyAll();
}
}
class producter implements Runnable{//这是一个生产者;需要生产东西;
private Rescoss r; //生产者需要调用到资源,或者说需要用那个盘子;
producter(Rescoss r){ //传入需要生产东西的名字;
this.r=r;
}
int x=100;
public void run(){
while(x>0){
if(x>0 && x<101){
r.set("馒头");
}
}
}
}
class Eater implements Runnable{ //这是一个消费者;消费都需要消费东西; 用线程来获取;
private Rescoss r; //消费者需要调用到资源,或者说是需要消费这个盘子里的东西;
Eater(Rescoss r){ //传入需要消费的产品;
this.r=r;
}
int x=100;
public void run(){
while(x>0){
if(x>0 && x<101){
r.get();
}
}
}
慕粉3947786
相关分类