如有这样的类
class Producer implements Runnable {
static int b;
public void run() {
for(int i=0; i<20; i++) {
Object wt = new Object(i);
ss.push(wt);
System.out.println("生产了:" + wt);
try {
Thread.sleep((int)(Math.random() * 200));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} public synchronized void m1(){}
}
Producer p = new Producer();
new Thread(p).start();
new Thread(p).start();
new Thread(p).start();与Producer p1 = new Producer();
Producer p2 = new Producer();
Producer p3 = new Producer();
new Thread(p1).start();
new Thread(p2).start();
new Thread(p3).start();同样启动三个线程,有什么区别呢?
一个是同一个对象的多个线程。
一个是多个对象的多个线程。对于里面的同步方法是怎么执行的呢?对于Producer中的静态变量b又是怎么样同步的呢?希望得到解答呀。
谢谢
class Producer implements Runnable {
static int b;
public void run() {
for(int i=0; i<20; i++) {
Object wt = new Object(i);
ss.push(wt);
System.out.println("生产了:" + wt);
try {
Thread.sleep((int)(Math.random() * 200));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} public synchronized void m1(){}
}
Producer p = new Producer();
new Thread(p).start();
new Thread(p).start();
new Thread(p).start();与Producer p1 = new Producer();
Producer p2 = new Producer();
Producer p3 = new Producer();
new Thread(p1).start();
new Thread(p2).start();
new Thread(p3).start();同样启动三个线程,有什么区别呢?
一个是同一个对象的多个线程。
一个是多个对象的多个线程。对于里面的同步方法是怎么执行的呢?对于Producer中的静态变量b又是怎么样同步的呢?希望得到解答呀。
谢谢
而一个对象多个线程,则有竞争。
对于static的,则没有区别,都存在竞争问题。请参考这个代码 一段生产者和消费者的简单多线程代码
还有 BlockingDeque 的使用,生产者和消费者的案例
It is never legal to start a thread more than once. In particular, a thread may not be restarted once it has completed execution.
题外话 如果不new新线程 理论上是不能restart要同步就在run方法中调用同步功能块 包括静态变量
谢谢你的回答,对于你的“类实例一级的同步问题”我是这么理解的:new 一对象就是在heap里分配一块内存,每个线程访问自己那块内存不会有竞争。
可同楼上,除了类实例一级还有什么级别么?多个线程如何竞争一个static变量,好像synchronized不起作用呀。
你的话很深奥啊~~听不大懂。。run方法调用静态变量用synchronized可以同步吗?
static是类级共享的 同步是可以 但你处理的是同一个变量
这算不算符合你对static同步的要求?
我现在糊涂好像一个类实例的多个线程和多个类的多个线程都是一个结果
我自己写了个例子,能跑起来,可以还是会发现有抢占错误:///////////////////////////////////////////////////////////////
import java.util.Stack;public class MyProducerConsumer { /**
* @param args
*/
public static void main(String[] args) {
// 顺序执行:
Basket basket = new Basket();
MyProducer mp = new MyProducer("厨师1", basket);
Thread t1 = new Thread(mp);
MyConsumer mc1 = new MyConsumer("食客1", basket);
Thread t2 = new Thread(mc1); MyConsumer mc2 = new MyConsumer("食客2", basket);
Thread t3 = new Thread(mc1);
MyConsumer mc3 = new MyConsumer("食客3", basket);
Thread t4 = new Thread(mc1); t1.start();
t2.start();
t3.start();
t4.start();
}}class MyProducer implements Runnable {
private Basket basket; private String proName; public MyProducer(String proName, Basket basket) {
this.basket = basket;
this.proName = proName;
} public void run() {
int i = 0;
while (i < 20) {
BaoZi baozi = new BaoZi(i++);
System.out.println(proName + "放包子:" + baozi.id);
this.basket.produce(baozi);
}
}
}class MyConsumer implements Runnable {
private Basket basket; private String cName; public MyConsumer(String consumerName, Basket basket) {
this.basket = basket;
this.cName = consumerName;
} public void run() {
int i = 5;
while (i > 0) {
BaoZi baozi = (BaoZi) this.basket.consume(); System.out.println(this.cName + "吃包子:" + baozi.id);
i--;
}
}
}class Basket {
private Stack<Object> basket = new Stack<Object>(); public static final int BasketCapacity = 10; public synchronized void produce(Object obj) {
if (basket.size() < BasketCapacity) {
basket.push(obj);
this.notifyAll();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else {
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} public synchronized Object consume() {
if (basket.size() == 0) {
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Object obj = basket.pop();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
this.notifyAll();
return obj; } public int Capacity() {
return this.basket.size();
}
}class BaoZi {
public BaoZi(int id) {
this.id = id;
} public int id;
}
///////////////////////////////////////////////////////////////
请贴到Eclipse中,这里比较难看代码解释:
一个生产者Producer生产包子,每人生产20个,每人每秒生产1个。3个消费者Consumer吃包子,每人吃5个,每人每2秒吃1个。
Basket的容量是10个,所以生产者产出满了篮子就wait,停止生产,等消费者吃了再生产直到产出20个。这段代码有问题,出在了3个消费者无视那个synchronized方法,一起抢篮子里的包子,所以2个线程抛出了Stack为空的异常。请大家帮我看一下。到底什么地方有问题呢?
虽然做WEB不大用到线程,但我想这个生产消费者的经典问题还是要牢牢掌握的呀,谢谢。