需求:生产者生产一个,消费者消费一个
问题引出
class Info{
private String name;
private String desc;
public Info(){
}
public Info(String name,String desc){
this.name = name;
this.desc = desc;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
@Override
public String toString() {
return "Info{" +
"name='" + name + '\'' +
", desc='" + desc + '\'' +
'}';
}
}
class Product implements Runnable{
private Info info;
public Product(Info info){
this.info = info;
}
@Override
public void run() {
for(int i = 0;i<100;i++){
if(i % 2 == 0){
this.info.setName("小郑");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.info.setDesc("钢笔");
}else{
this.info.setName("小李");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.info.setDesc("笔记本");
}
System.err.println(info.getName()+" 生产->"+info.getDesc());
}
}
}
class Consume implements Runnable{
private Info info;
public Consume(Info info){
this.info = info;
}
@Override
public void run() {
for(int i = 0; i< 100;i++){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.err.println(info.getName()+"消费->"+info.getDesc());
}
}
}
public class ProductCustumer {
public static void main(String args[]){
Info info = new Info();
new Thread(new Product(info)).start();
new Thread(new Consume(info)).start();
}
}
结果:
小郑消费->null
小郑 生产->钢笔
小李消费->笔记本
小李 生产->笔记本
小郑消费->笔记本
小郑 生产->钢笔
小李 生产->笔记本
小李消费->笔记本
小郑 生产->钢笔
小李消费->钢笔
小李消费->钢笔
小李 生产->笔记本
小郑消费->笔记本
小郑 生产->钢笔
小李 生产->笔记本
小李消费->笔记本
小郑 生产->钢笔
小郑消费->钢笔
小李消费->笔记本
小李 生产->笔记本
小郑 生产->钢笔
小李消费->钢笔
小李消费->钢笔
小李 生产->笔记本
小郑消费->笔记本
小郑 生产->钢笔
小李 生产->笔记本
小李消费->笔记本
小郑消费->钢笔
小郑 生产->钢笔
小李 生产->笔记本
小李消费->笔记本
小郑 生产->钢笔
小郑消费->钢笔
小李 生产->笔记本
小李消费->笔记本
小郑 生产->钢笔
小李消费->钢笔
小李消费->笔记本
小李 生产->笔记本
小郑 生产->钢笔
小郑消费->钢笔
小李消费->笔记本
小李 生产->笔记本
小郑消费->钢笔
小郑 生产->钢笔
小李消费->笔记本
小李 生产->笔记本
小郑消费->笔记本
小郑 生产->钢笔
小李消费->钢笔
小李 生产->笔记本
小郑消费->钢笔
小郑 生产->钢笔
小李消费->笔记本
小李 生产->笔记本
小郑消费->笔记本
小郑 生产->钢笔
小李消费->笔记本
小李 生产->笔记本
小郑消费->笔记本
小郑 生产->钢笔
小李消费->钢笔
小李 生产->笔记本
小郑消费->笔记本
小郑 生产->钢笔
小李消费->笔记本
小李 生产->笔记本
小郑消费->钢笔
小郑 生产->钢笔
小李消费->钢笔
小李 生产->笔记本
小郑消费->钢笔
小郑 生产->钢笔
小李消费->笔记本
小李 生产->笔记本
小郑消费->笔记本
小郑 生产->钢笔
小李 生产->笔记本
小李消费->笔记本
小郑 生产->钢笔
小郑消费->钢笔
小李消费->笔记本
小李 生产->笔记本
小郑 生产->钢笔
小郑消费->钢笔
小李消费->钢笔
小李 生产->笔记本
小郑消费->笔记本
小郑 生产->钢笔
小李消费->钢笔
小李 生产->笔记本
小郑 生产->钢笔
小郑消费->钢笔
小李消费->笔记本
小李 生产->笔记本
小郑消费->笔记本
小郑 生产->钢笔
小李 生产->笔记本
小李消费->笔记本
小郑消费->钢笔
小郑 生产->钢笔
小李消费->钢笔
小李 生产->笔记本
小郑 生产->钢笔
小李消费->钢笔
小李消费->笔记本
小李 生产->笔记本
小郑消费->笔记本
小郑 生产->钢笔
小李 生产->笔记本
小李消费->笔记本
小郑 生产->钢笔
小郑消费->钢笔
小李 生产->笔记本
小李消费->笔记本
小郑消费->笔记本
小郑 生产->钢笔
小李消费->钢笔
小李 生产->笔记本
小郑 生产->钢笔
小郑消费->钢笔
小李消费->钢笔
小李 生产->笔记本
小郑 生产->钢笔
小郑消费->钢笔
小李 生产->笔记本
小李消费->笔记本
小郑 生产->钢笔
小郑消费->钢笔
小李 生产->笔记本
小郑消费->笔记本
小郑 生产->钢笔
小李消费->钢笔
小李 生产->笔记本
小郑消费->笔记本
小郑 生产->钢笔
小郑消费->钢笔
小李 生产->笔记本
小李消费->笔记本
小郑消费->钢笔
小郑 生产->钢笔
小李 生产->笔记本
小郑消费->笔记本
小郑 生产->钢笔
小郑消费->钢笔
小李 生产->笔记本
小李消费->笔记本
小郑 生产->钢笔
小郑消费->钢笔
小李消费->笔记本
小李 生产->笔记本
小郑 生产->钢笔
小郑消费->钢笔
小李 生产->笔记本
小郑消费->笔记本
小郑 生产->钢笔
小李消费->钢笔
小李 生产->笔记本
小李消费->笔记本
小郑消费->笔记本
小郑 生产->钢笔
小李消费->钢笔
小李 生产->笔记本
小郑消费->笔记本
小郑 生产->钢笔
小李消费->钢笔
小李 生产->笔记本
小郑消费->笔记本
小郑 生产->钢笔
小李消费->笔记本
小李 生产->笔记本
小郑消费->笔记本
小郑 生产->钢笔
小李消费->钢笔
小李 生产->笔记本
小郑消费->钢笔
小郑 生产->钢笔
小李消费->笔记本
小李 生产->笔记本
小郑 生产->钢笔
小李消费->钢笔
小李 生产->笔记本
小郑消费->笔记本
小郑消费->笔记本
小郑 生产->钢笔
小李 生产->笔记本
小郑消费->笔记本
小郑 生产->钢笔
小郑消费->钢笔
小李消费->钢笔
小李 生产->笔记本
小郑 生产->钢笔
小郑消费->钢笔
小李 生产->笔记本
小李消费->笔记本
小郑 生产->钢笔
小李消费->钢笔
小李消费->笔记本
小李 生产->笔记本
Process finished with exit code 0
有上面结果可以看出产生了两个问题1.生产人和产物不对应,2.违背生产一个消费一个规则
解决 生产人和产物不对应问题
生产人和产物不对应是线程不同步导致,修改代码如下
class Info{
private String name;
private String desc;
public synchronized void set(String name,String desc){
this.name = name;
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.desc = desc;
System.err.println(name+" 生产->"+desc);
}
public synchronized void get(){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.err.println(name+" 消费->"+desc);
}
}
class Product implements Runnable{
private Info info;
public Product(Info info){
this.info = info;
}
@Override
public void run() {
for(int i = 0;i<100;i++){
if(i % 2 == 0){
info.set("小郑","钢笔");
}else{
info.set("小李","笔记本");
}
}
}
}
class Consume implements Runnable{
private Info info;
public Consume(Info info){
this.info = info;
}
@Override
public void run() {
for(int i = 0; i< 100;i++){
info.get();
}
}
}
public class ProductCustumer {
public static void main(String args[]){
Info info = new Info();
new Thread(new Product(info)).start();
new Thread(new Consume(info)).start();
}
}
结果:
小郑 生产->钢笔
小李 生产->笔记本
小郑 生产->钢笔
小李 生产->笔记本
小郑 生产->钢笔
小李 生产->笔记本
小郑 生产->钢笔
小李 生产->笔记本
小李 消费->笔记本
小李 消费->笔记本
小李 消费->笔记本
小李 消费->笔记本
小李 消费->笔记本
小李 消费->笔记本
小李 消费->笔记本
解决 违背生产一个消费一个规则
package a002;
/**
* Created by Administrator on 2018/2/23 0023.
*/
class Info{
// falg true 可以生产,但是不能消费 false 可以消费,但不可以生产
private Boolean falg = true; //默认为true 先生产
private String name;
private String desc;
public synchronized void set(String name,String desc){
if(falg == false){ //等待消费
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.name = name;
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.desc = desc;
System.err.println(name+" 生产->"+desc);
//生产完成修改开关
this.falg = false;
//唤醒生产线程
notify();
}
public synchronized void get(){
if(falg){ //等待生产
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.err.println(name+" 消费->"+desc);
falg = true;
notify();
}
}
class Product implements Runnable{
private Info info;
public Product(Info info){
this.info = info;
}
@Override
public void run() {
for(int i = 0;i<100;i++){
if(i % 2 == 0){
info.set("小郑","钢笔");
}else{
info.set("小李","笔记本");
}
}
}
}
class Consume implements Runnable{
private Info info;
public Consume(Info info){
this.info = info;
}
@Override
public void run() {
for(int i = 0; i< 100;i++){
info.get();
}
}
}
public class ProductCustumer {
public static void main(String args[]){
Info info = new Info();
new Thread(new Product(info)).start();
new Thread(new Consume(info)).start();
}
}
结果:
小郑 生产->钢笔
小郑 消费->钢笔
小李 生产->笔记本
小李 消费->笔记本
小郑 生产->钢笔
小郑 消费->钢笔
小李 生产->笔记本
小李 消费->笔记本
小郑 生产->钢笔
小郑 消费->钢笔
小李 生产->笔记本
小李 消费->笔记本
小郑 生产->钢笔
小郑 消费->钢笔
小李 生产->笔记本
小李 消费->笔记本