package thread.com.cn;
//资源类
class Resource{
//资源名称 比如 存储煤
String name;
int num;
//定义一个boolean类型标记 默认值为false 来判断仓库中是否有煤 如果为true表示仓库中有煤 需要等待 如果为false表示仓库中没有煤 不用等待
boolean flag=false;
public synchronized void set(String name,int num) throws InterruptedException {
if(this.flag){
wait();
}
this.name=name; this.num=num;
System.out.println("往仓库运输煤:" + this.name + "::" + this.num);
this.flag=true;
this.notify();
}
public synchronized void out() throws InterruptedException {
if(!this.flag){
wait();
}
System.out.println("从仓库中取走煤:" + this.name + "-----" + this.num);
this.flag=false;
this.notify();
}
}
class Input implements Runnable{
Resource r;
Input(Resource r){
this.r=r;
}
public void run() {
int x=0;
while(true) {
if(x==0){
try {
r.set("烟煤",1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}else{
try {
r.set("无烟煤",2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
x=(x+1)%2;
// synchronized (r) {
// if(r.flag){
// try {
// r.wait();
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// }
// if (x == 0) {
// r.name = "烟煤";
// r.num = 1;
// } else {
// r.name = "无烟煤";
// r.num = 2;
// }
// x = (x + 1) % 2;
// System.out.println("往仓库运输煤:" + r.name + "::" + r.num);
// r.flag=true;
// r.notify();
// }
}
}
}
class Output implements Runnable{
Resource r;
Output(Resource r){
this.r=r;
}
@Override
public void run() {
while (true) {
try {
r.out();
} catch (InterruptedException e) {
e.printStackTrace();
}
// synchronized (r) {
// if(!r.flag){
// try {
// r.wait();
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// }
// System.out.println("从仓库中取走煤:" + r.name + "-----" + r.num);
// r.flag=false;
// r.notify();
// }
}
}
}
public class ThreadDemo01 {
public static void main(String[] args) {
//创建资源对象
Resource r=new Resource();
//准备卡车 1
Input in=new Input(r);
//准备卡车2
Output out=new Output(r);
//创建线程
Thread t=new Thread(in);
Thread t1=new Thread(out);
t.start();
t1.start();
}
}
package thread.com.cn;
class Resouce01{
//商品名称
String name;
//记录商品生产次数
int count;
boolean flag=false;
//当多个线程同时生产和消费时 会出现重复消费情况 主要原因是notify方法会唤醒本方线程
// 且被唤醒线程不会重复判断标记 导致程序往下执行 造成重复消费 说以判断标记一般改为while循环
//t1 t2
public synchronized void set(String name) throws InterruptedException {
while(this.flag){//t1获取执行资格 t2放弃执行资格
wait();
}
this.name=name+":::"+count++;
System.out.println("生产者生产:::"+this.name);
this.flag=true;
this.notifyAll();
}
//t3 t4
public synchronized void out() throws InterruptedException {
while(!flag){//t3获取执行资格 t4放弃执行资格
wait();
}
System.out.println("消费者消费:-------"+this.name);
this.flag=false;
this.notifyAll();
}
}
class Producer implements Runnable{
Resouce01 r;
Producer(Resouce01 r){
this.r=r;
}
public void run() {
while(true){
try {
r.set("商品");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Consumer implements Runnable{
Resouce01 r;
Consumer(Resouce01 r){
this.r=r;
}
public void run() {
while(true){
try {
r.out();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class ThreadDemo02 {
public static void main(String[] args) {
Resouce01 r=new Resouce01();
Producer p=new Producer(r);
Consumer c=new Consumer(r);
Thread t1=new Thread(p);
Thread t2=new Thread(p);
Thread t3=new Thread(c);
Thread t4=new Thread(c);
t1.start();
t2.start();
t3.start();
t4.start();
}
}