生产者与消费者问题,篮子为SyncStack,物品为Woto(窝头),现在问题是,多个生产者生产,Woto有个静态属性id,每生产一个,id+1,但程序在运行时,(多次试验),有时候第一个记录id不是1,而是被多个线程修改了之后的值,
请问如果保证这个id值线程同步,该问题是在看马士兵老师的javase视频的时候遇到的,我修改了原来的没有同步方法的id产生方法,代码如下,package thread;import java.util.ArrayList;
import java.util.List;public class ProducerAndCustomer { /**
* @param args
*/
public static void main(String[] args) {
SyncStack stack = new SyncStack();
Producer pc = new Producer(stack);
Customer cs = new Customer(stack);
new Thread(pc).start();
new Thread(pc).start();
new Thread(pc).start();
new Thread(cs).start();
}}class SyncStack {
List<Woto> list = new ArrayList<Woto>();
public static final int capacity = 3;
// 大于或等于 容量则等待
synchronized void push(Woto wt) {
while (list.size()>capacity) {
try {
this.wait();
}catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("生产了wotou" + wt);
list.add(wt);
this.notify();
} public synchronized Woto pop() {
while (list.isEmpty()) {
try {
this.wait();
}catch (InterruptedException e) {
e.printStackTrace();
}
}
//取得最后放入的窝头
Woto wt = list.remove(list.size()-1);
System.out.println("取了wotou" + wt);
this.notify();
return wt;
}
}class Woto {
public static int id = 0;
public Woto() {
synchronized (this.getClass()) {
idAdd();
}
}
private synchronized void idAdd() {
id++;
}
// public static synchronized Woto getWoto() {
// return new Woto();
// }
public String toString() {
return "第" + id + "个窝头";
}
}class Producer implements Runnable{
SyncStack stack;
public Producer(SyncStack stack) {
this.stack = stack;
} @Override
public void run() {
for (int i=0; i<SyncStack.capacity; i++) {
Woto wt = new Woto();
stack.push(wt);
try {
Thread.sleep((int)Math.random()*200);
}catch(InterruptedException e) {
e.printStackTrace();
}
}
}
}class Customer implements Runnable {
SyncStack stack;
public Customer(SyncStack stack) {
this.stack = stack;
}
@Override
public void run() {
for (int i=0; i<SyncStack.capacity; i++) {
Woto wt = stack.pop();
try {
Thread.sleep((int)Math.random()*200);
}catch(InterruptedException e) {
e.printStackTrace();
}
}
}
}
请问如果保证这个id值线程同步,该问题是在看马士兵老师的javase视频的时候遇到的,我修改了原来的没有同步方法的id产生方法,代码如下,package thread;import java.util.ArrayList;
import java.util.List;public class ProducerAndCustomer { /**
* @param args
*/
public static void main(String[] args) {
SyncStack stack = new SyncStack();
Producer pc = new Producer(stack);
Customer cs = new Customer(stack);
new Thread(pc).start();
new Thread(pc).start();
new Thread(pc).start();
new Thread(cs).start();
}}class SyncStack {
List<Woto> list = new ArrayList<Woto>();
public static final int capacity = 3;
// 大于或等于 容量则等待
synchronized void push(Woto wt) {
while (list.size()>capacity) {
try {
this.wait();
}catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("生产了wotou" + wt);
list.add(wt);
this.notify();
} public synchronized Woto pop() {
while (list.isEmpty()) {
try {
this.wait();
}catch (InterruptedException e) {
e.printStackTrace();
}
}
//取得最后放入的窝头
Woto wt = list.remove(list.size()-1);
System.out.println("取了wotou" + wt);
this.notify();
return wt;
}
}class Woto {
public static int id = 0;
public Woto() {
synchronized (this.getClass()) {
idAdd();
}
}
private synchronized void idAdd() {
id++;
}
// public static synchronized Woto getWoto() {
// return new Woto();
// }
public String toString() {
return "第" + id + "个窝头";
}
}class Producer implements Runnable{
SyncStack stack;
public Producer(SyncStack stack) {
this.stack = stack;
} @Override
public void run() {
for (int i=0; i<SyncStack.capacity; i++) {
Woto wt = new Woto();
stack.push(wt);
try {
Thread.sleep((int)Math.random()*200);
}catch(InterruptedException e) {
e.printStackTrace();
}
}
}
}class Customer implements Runnable {
SyncStack stack;
public Customer(SyncStack stack) {
this.stack = stack;
}
@Override
public void run() {
for (int i=0; i<SyncStack.capacity; i++) {
Woto wt = stack.pop();
try {
Thread.sleep((int)Math.random()*200);
}catch(InterruptedException e) {
e.printStackTrace();
}
}
}
}
将
class Woto {
public static int id = 0;
public Woto() {
synchronized (this.getClass()) {
idAdd();
}
}
private synchronized void idAdd() {
id++;
}
// public static synchronized Woto getWoto() {
// return new Woto();
// }
public String toString() {
return "第" + id + "个窝头";
}
}
改为
class Woto {
public static AtomicInteger id = new AtomicInteger(0);
public Woto() {
idAdd();
}
private void idAdd() {
id.incrementAndGet();
}
public String toString() {
return "第" + id.get() + "个窝头";
}
}
private static volatile int id = 0; // 私有化,保护起来,不能被随意访问
public static synchronized int getNewId() { // 得到新的id ,应该用static,跟变量一致。
return ++id;
}
}