生产者和消费者指的是两个不同线程类对象操作同一类资源的情况。
- 生产者负责生产数据,消费者负责取走数据
- 生产者每生产一组数据,消费者就要取走一组数据
- 标准的生产者--消费者代码:
package cn.dujiang.demo;
class Info {
private String title ;
private String content ;
public void setTitle(String title){
this.title = title ;
}
public String getTitle() {
return title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
class Productor implements Runnable {
private Info info ;
public Productor(Info info){
this.info = info ;
}
@Override
public void run() {
for (int x = 0; x < 100 ; x++) {
if (x % 2 == 0) { //偶数
this.info.setTitle("第1组数据");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.info.setContent("1.数据说明");
}else {
this.info.setTitle("第2组数据");
this.info.setContent("2.数据说明");
}
}
}
}
class Customer implements Runnable {
private Info info ;
public Customer(Info info) {
this.info = info ;
}
@Override
public void run() {
for (int x = 0; x < 100; x++) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(this.info.getTitle() + "-" + this.info.getContent());
}
}
}
public class TestDemo {
public static void main(String[] args) {
Info info = new Info() ;
new Thread(new Productor(info)).start();
new Thread(new Customer(info)).start();
}
}
/*
* 以上的代码的运行结果:
第1组数据-2.数据说明
第1组数据-2.数据说明
第2组数据-2.数据说明
第2组数据-2.数据说明
第2组数据-2.数据说明....
|-数据错位,发现不再是一个所需要的完整数据;
|-数据重复取出,数据重复设置。*/
- 解决了数据错乱的生产者--消费者问题
package cn.dujiang.demo;
class Info {
private String title ;
private String content ;
public synchronized void set(String title,String content){
this.title = title ;
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.content = content ;
}
public synchronized void get(){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(this.title + "-" + this.content);
}
}
class Productor implements Runnable {
private Info info ;
public Productor(Info info){
this.info = info ;
}
@Override
public void run() {
for (int x = 0; x < 100 ; x++) {
if (x % 2 == 0) { //偶数
this.info.set("第1组数据","1.数据说明");
}else {
this.info.set("第2组数据","2.数据说明");
}
}
}
}
class Customer implements Runnable {
private Info info ;
public Customer(Info info) {
this.info = info ;
}
@Override
public void run() {
for (int x = 0; x < 100; x++) {
this.info.get();
}
}
}
public class TestDemo {
public static void main(String[] args) {
Info info = new Info() ;
new Thread(new Productor(info)).start();
new Thread(new Customer(info)).start();
}
}
/*
* 以上的代码的运行结果:
第1组数据-1.数据说明
第1组数据-1.数据说明
第2组数据-2.数据说明
第2组数据-2.数据说明
第2组数据-2.数据说明....
以上代码解决了数据错乱的问题,得到了很好的解决,但是,重复问题变得严重了
****************************************
*数据错位完全是因为非同步操作所造成的,所以应该使用同步处理。
*以为,取和设置是两个不同的操作
*/
- 解决了线程重复的生产者消费者问题:
package cn.dujiang.demo;
class Info {
private String title ;
private String content ;
private boolean flag = true ;
/*flag = true 表示可以生产,但是不可以取走
flag = false 表示可以取走,但是不可以生产*/
public synchronized void set(String title,String content){
//重复进入到了set()方法里,发现不能够生产,所以要等待
if (this.flag == false) {
try {
super.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.title = title ;
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.content = content ;
this.flag = false ; //修改生产标记
super.notify(); //唤醒其他等待线程
}
public synchronized void get(){
if (this.flag == true) { //还没生产,继续等待
try {
super.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(this.title + "-" + this.content);
this.flag = true ;
super.notify();
}
}
class Productor implements Runnable {
private Info info ;
public Productor(Info info){
this.info = info ;
}
@Override
public void run() {
for (int x = 0; x < 100 ; x++) {
if (x % 2 == 0) { //偶数
this.info.set("第1组数据","1.数据说明");
}else {
this.info.set("第2组数据","2.数据说明");
}
}
}
}
class Customer implements Runnable {
private Info info ;
public Customer(Info info) {
this.info = info ;
}
@Override
public void run() {
for (int x = 0; x < 100; x++) {
this.info.get();
}
}
}
public class TestDemo {
public static void main(String[] args) {
Info info = new Info() ;
new Thread(new Productor(info)).start();
new Thread(new Customer(info)).start();
}
}
/*
* 以上的代码的运行结果:
第1组数据-1.数据说明
第2组数据-2.数据说明
第1组数据-1.数据说明
第2组数据-2.数据说明
第1组数据-1.数据说明
第2组数据-2.数据说明....
生产者和消费者问题全部解决,但是执行会变慢,不过这就是经典的
生产者消费者问题
****************************************
*/
总结:以上便是经典的生产--消费线程同步问题的解决
℃江