package Thread3;
import java.sql.PreparedStatement;
/**
* 资源
*/
public class Resource {
private volatile int times;
private String name;
private int age;
private boolean flag = false;//当前是否已执行set操作,是否交替执行信号,置于末尾,notify()前
private int setTimes;
private int getTimes;
public void setTimes(int times) {
this.times = times;
}
public int getTimes() {
return times;
}
public void decTimes() {
this.times--;
}
public boolean hasTimes() {
return 0 < this.times;
// return true;
}
// public void setName(String name) {
// this.name = name;
// }
//
// public void setAge(int age) {
// this.age = age;
// }
//
// public int getAge() {
// return age;
// }
//
// public String getName() {
// return name;
// }
@Override
public String toString() {
return "Resource{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public synchronized void set(String name, int age) throws InterruptedException {
if (flag) {
//线程未交替执行,进行阻塞唤醒其他线程(线程是随机并发或并行执行的,所有要对执行顺序设置和获取进行干预)
System.out.println("--------------" + Thread.currentThread().getName() + " -----flag:" + flag);
wait();//当前线程进入阻塞状态,等待消费者进程消费数据后,再往下执行
System.out.println("--------------------------------------------:flag:true");
}
this.setTimes++;
this.name = name;
this.age = age;
flag = true;
notify();//唤醒其他任意线程,使唤醒线(这里指消费者)程进入就绪状态
}
public synchronized String get() throws InterruptedException {
if (!flag) {
System.out.println("-------------" + Thread.currentThread().getName() + " -----flag:" + flag);
wait();
System.out.println("---------------------------------------:flag:false");
}
// System.out.println(toString());
this.getTimes++;
flag = false;
notify();
return toString();
}
public int getSetTimes() {
return setTimes;
}
public int getGetTimes() {
return getTimes;
}
}
package Thread3;
/**
* 生产者
*/
public class Input implements Runnable {
private Resource resource;
Input(Resource resource) {
this.resource = resource;
}
@Override
public void run() {
int x = 0;
while (resource.hasTimes()) {
System.out.println(Thread.currentThread().getName() + " times:" + resource.getTimes());
if (0 == x++ % 2) {
// resource.setAge(1);
// resource.setName("a");
try {
resource.set("a", 1);
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
// resource.setName("b");
// resource.setAge(2);
try {
resource.set("b", 2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// x = (x + 1) % 2;
resource.decTimes();
}
}
}
package Thread3;
/**
* 消费者
*/
public class Output implements Runnable {
private Resource resource;
Output(Resource resource) {
this.resource = resource;
}
@Override
public void run() {
while (resource.hasTimes()) {
System.out.println(Thread.currentThread().getName() + " times::" + resource.getTimes());
try {
System.out.println("result:" + resource.get());
// resource.get();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
package Thread3;
public class Run {
public static void main(String[] args) throws InterruptedException {
Resource resource = new Resource();
resource.setTimes(20);
Input input = new Input(resource);
Output output = new Output(resource);
//生产者与消费者可以并行执行
Thread thread = new Thread(input, "生产者");
Thread thread1 = new Thread(output, "消费者");
// Thread thread2 = new Thread(input);
// Thread thread3 = new Thread(output);
thread.start();
// thread2.start();
thread1.start();
// thread3.start();
thread.join();
thread1.join();
// thread2.join();
// thread3.join();
System.out.println("setTimes:" + resource.getSetTimes());
System.out.println("getTimes:" + resource.getGetTimes());
}
}
测试结果
消费者 times::20
生产者 times:20
-------------消费者 -----flag:false
---------------------------------------:flag:false
生产者 times:19
生产者 times:18
--------------生产者 -----flag:true
result:Resource{name='a', age=1}
消费者 times::18
result:Resource{name='b', age=2}
--------------------------------------------:flag:true
消费者 times::18
生产者 times:17
result:Resource{name='a', age=1}
生产者 times:16
消费者 times::16
--------------生产者 -----flag:true
result:Resource{name='b', age=2}
--------------------------------------------:flag:true
消费者 times::16
生产者 times:15
result:Resource{name='a', age=1}
生产者 times:14
消费者 times::14
--------------生产者 -----flag:true
result:Resource{name='b', age=2}
--------------------------------------------:flag:true
消费者 times::14
生产者 times:13
result:Resource{name='a', age=1}
生产者 times:12
消费者 times::12
--------------生产者 -----flag:true
result:Resource{name='b', age=2}
--------------------------------------------:flag:true
消费者 times::12
生产者 times:11
result:Resource{name='a', age=1}
生产者 times:10
消费者 times::10
--------------生产者 -----flag:true
result:Resource{name='b', age=2}
--------------------------------------------:flag:true
消费者 times::10
生产者 times:9
生产者 times:8
--------------生产者 -----flag:true
result:Resource{name='a', age=1}
消费者 times::8
result:Resource{name='b', age=2}
--------------------------------------------:flag:true
消费者 times::8
生产者 times:7
result:Resource{name='a', age=1}
生产者 times:6
消费者 times::6
--------------生产者 -----flag:true
--------------------------------------------:flag:true
result:Resource{name='b', age=2}
生产者 times:5
消费者 times::5
--------------生产者 -----flag:true
result:Resource{name='a', age=1}
--------------------------------------------:flag:true
消费者 times::5
生产者 times:4
result:Resource{name='b', age=2}
生产者 times:3
消费者 times::3
--------------生产者 -----flag:true
result:Resource{name='a', age=1}
--------------------------------------------:flag:true
消费者 times::3
生产者 times:2
result:Resource{name='b', age=2}
生产者 times:1
消费者 times::1
--------------生产者 -----flag:true
result:Resource{name='a', age=1}
--------------------------------------------:flag:true
消费者 times::1
result:Resource{name='b', age=2}
setTimes:20
getTimes:20