消息关闭
    暂无新消息!

synchronized为何无法保证数据同步?

问题作者 : 风之2017-06-29发布
代码如下,当只有1个生产者1个消费者,正常;但是当有2个消费者,出现错误,麻烦大神帮忙分析下,为何synchronized没有锁住apple?

// 生产内容
public class Apple {
private int i = 0;

public int getI() {
return i;
}

public void setI(int i) {
this.i = i;
}

}
// 消费者
public class Consumer extends Thread{
private String name;

private Apple apple;

public Consumer(Apple apple, String name){
this.apple = apple;
this.name = name;
}

@Override
public void run() {
while (true){
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
synchronized (apple) {
if (apple.getI() == 0){
try {
System.out.println(name + "放开苹果,当前值:"+ apple.getI());
apple.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
int i = apple.getI()-1;
apple.setI(i);
System.out.println(name + " is Running,值:"+ apple.getI());
apple.notifyAll();
}
}
}
}
// 生产者
public class Producter extends Thread{ 
private String name;

private Apple apple;

public Producter(Apple apple, String name){
this.apple = apple;
this.name = name;
}

@Override
public void run() {
while (true){
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
synchronized (apple) {
if (apple.getI() > 0){
try {
System.out.println(name + "放开苹果,当前值:"+ apple.getI());
apple.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
int i = 1 + apple.getI();
apple.setI(i);
System.out.println(name + " is Running,值:"+ apple.getI());
apple.notifyAll();
}
}
}

public static void main(String[] args) {
Apple apple = new Apple();
Producter tha = new Producter(apple, "a");
Consumer thb = new Consumer(apple, "b");
Consumer thc = new Consumer(apple, "c");

tha.start();
thb.start();
// thc.start();
}
}


7个回答

︿ 2
我的理解是,
1.多消费者情况下,if 判断条件后必须跟else;因为如果一个消费者进入等待后,因为wait释放锁的原因,可能使下一个消费者也进入等待; 那么在两个消费者再次进入后很可能在0的情况下继续运行造成值为-1
2.单消费者情况,无需else,因为在一个消费者进入等待后,必然有生产者提供生产,所以不会造成值为-1
有错的地方望指正!
︿ 2
b is Running,值:1
a is Running,值:9
b is Running,值:2
a is Running,值:8
b is Running,值:3
a is Running,值:7
a is Running,值:6
b is Running,值:4
b is Running,值:5
a is Running,值:5
b is Running,值:6
a is Running,值:4
a is Running,值:3
b is Running,值:7
a is Running,值:2
b is Running,值:8
a is Running,值:1
b is Running,值:9
a is Running,值:0
b is Running,值:10
a放开苹果,当前值:0
b放开苹果,当前值:10/你想要的结果是这样还是什么样??????
︿ 2
你wait的时候释放锁了,所以接下来的线程可以继续进入,可以考虑用sleep
︿ 1
 Producter tha = new Producter(new Apple(), "a");
        Consumer thb = new Consumer(new Apple(), "b"); 你试试这个
︿ 0
你的synchronized 放错地方了


ublic class Apple {
    private int i = 0;
 
    public synchronized int getI() {
        return i;
    }
 
    public synchronized void setI(int i) {
        this.i = i;
    }
     
}