- 浏览: 930904 次
- 性别:
- 来自: 魔都
文章分类
- 全部博客 (745)
- MultiThread (19)
- My Plan (118)
- JavaBasic (61)
- MyInterview (104)
- InternetTechnique (5)
- ProjectConclusion (1)
- Maven (5)
- MogoDb (5)
- Hadoop (11)
- Memcached (6)
- TechniqueCollect (1)
- Ibaits (1)
- Android (34)
- ItLife (40)
- Tree (2)
- ProjectArchitect (7)
- Open Source (3)
- liunx (5)
- socket (8)
- Spring (27)
- DesginPattern (35)
- WebBasic (13)
- English (13)
- structs (1)
- structs2 (2)
- Oracle (17)
- Hibernate (2)
- JavaScript (4)
- Jdbc (1)
- Jvm (15)
- Ibatis (1)
- DataStructures (13)
- Https/Socket/Tcp/Ip (3)
- Linux (4)
- Webservice (7)
- Io (2)
- Svn (1)
- Css (1)
- Ajax (1)
- ExtJs (1)
- UML (2)
- DataBase (6)
- BankTechnique (3)
- SpringMvc (3)
- Nio (3)
- Load Balancing/Cluster (3)
- Tools (1)
- javaPerformanceOptimization (8)
- Lucene(SEO) (1)
- My Think (80)
- NodeJs (1)
- Quartz (1)
- Distributed-java (1)
- MySql (7)
- Project (4)
- junit (4)
- framework (1)
- enCache (1)
- git (2)
- SCJP (1)
- sd (1)
最新评论
-
lkjxshi:
你都这水平了还考这个证干嘛
SCJP 认证考试指南 -
钟逸华:
问的真多
百度java开发面试题(转) -
zuimeitulip:
觉得我就是这样的,从小阅读量就很少,导致现在的读的速度非常慢, ...
让读书成为一种习惯 -
DDT_123456:
我觉得你是不符合要求。问你hashmap的那个问题,你那样回答 ...
阿里面试2(转) -
jingjing0907:
刚刚写了很多读过此博客的感受,竟然没有发上去,以为我注册账号还 ...
让读书成为一种习惯
学到多线程,编了一个简单地电脑城进出货模拟系统。
代码有点长,主要部分如下所述:
有三方:厂家,电脑城,顾客
厂家2个,一个生产主板,一个生产显卡。
顾客有2个,他们各自不断购买主板和显卡。
电脑城有一个,卖显卡和主板。
限于篇幅问题,摘录主要代码如下:
--------------------------厂家类---------------------------------------
Java代码
public class Mainboardretailer implements Runnable// 主板厂家
{
public void run()
{
while(true)
{
电脑城.stockMainboard(deliverMB("MSI"));//不断向电脑城供货
}
}
public Mainboard deliverMB(String 主板名)
{
return 主板;
}
}
public class Videocardretailer implements Runnable// 显卡厂家
{
public void run()
{
while(true)
{
电脑城.stockVideocard(deliverVC("ATI"));//不断向电脑城供货
}
}
public videocard deliverMB(String 显卡名)
{
return 显卡;
}
}
-------------------------------------顾客类-------------------------------------------
Java代码
public class customer implements Runnable
{
public void run()
{
while(true)
{
buyVC("ATI");
//顾客不断购买显卡和主板
buyMB("MSI");
}
}
}
-----------------------------电脑城类-----------------------------------------
Java代码
public class ComputerCenter
{
int MAXVCSTORE = 100;//货仓容量
int MAXMBSTORE = 100;//货仓容量
private static LinkedList<Videocard> VideocardQty = new LinkedList<Videocard>();//显卡货仓
private static LinkedList<Mainboard> MainboardQty = new LinkedList<Mainboard>();//主板货仓
public synchronized void stockVideocard(Videocard VCname)
{
if(VideocardQty.size() >= MAXVCSTORE)
{
System.out.println("ComputerCenter: the VC storage is MAX");
try
{
wait();//---------------------当存货过多时。通知厂商等待。
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
VideocardQty.add(VCname);
notify();//----------------------------唤醒消费者消费
}
public synchronized void stockMainboard(Mainboard MBname)
{
if(MainboardQty.size() >= MAXVCSTORE)
{
System.out.println("ComputerCenter: the MB storage is MAX");
try
{
wait();//----------------------当存货过多时。通知厂商等待。
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
MainboardQty.add(MBname);
notify();//-----------------------------唤醒消费者消费
}
public synchronized Videocard sellVideocard(String VCname)
{
if(VideocardQty.size() <= 0)
{
try
{
wait();//-----------------没有存货时,通知消费者等待
}catch(Exception e)
{
e.printStackTrace();
}
}
notify();//----------------------------------唤醒厂商
return MyVideocard;
}
public synchronized Mainboard sellMainboard(String MBname)
{
if(MainboardQty.size() <= 0)
{
try
{
wait();//-----------------没有存货时,通知消费者等待
}catch(Exception e)
{
e.printStackTrace();
}
}
notify();//----------------------------------唤醒厂商
return MyMainboard;
}
public static void main(String[] args)
{
ComputerCenter MyCC = new ComputerCenter();
new customer(MyCC,"Jack").start();
new customer(MyCC,"Tom").start();
new Mainboardretailer(MyCC).start();
new Videocardretailer(MyCC).start();
}
}
现在出现了这样的一个问题:
1.如果有两个消费者同时等待,厂家生产后唤醒其中消费者A,消费者A购买完毕后会唤醒消费者B--不合逻辑。
2.如果购买显卡地消费者A在等待,电脑城从主板厂商进货了主板以后会唤醒消费者A。同样的情况也发生在购买主板的消费者B身上。
3.如果两家厂商在等待消费者购买商品,此时消费者A购买了主板,货仓主板数量-1,然后有可能唤醒显卡厂商而没有唤醒主板厂商进行生产。
4.如果两家厂商正在等待消费者购买商品,此时显卡厂商被唤醒后,可能立刻唤醒主板厂商生产主板,令到商品数量超出仓库上限。
我想,有没有什么办法,可以指定唤醒某个线程?如果可以,那问题就容易解决了。
------------------------------------------------------------------------------------------------------------------
问题补充:
xmind 写道
主要问题是 显卡 没了,等显卡送来,主板没了等主板送来。
不能人家来买显卡的,你进来一个主板也通知人家来买。
写了个例子,你看看。
Java代码
class ComputerCenter {
private static Object VIDEO = new Object();
private static Object MAINB = new Object();
private static Integer videoN = 10;
private static Integer MainbN = 10;
public void stockVd() {
synchronized(VIDEO) {
if(videoN >= 20) {
System.out.println("ComputerCenter: the VC storage is MAX");
try {VIDEO.wait();} catch (Exception e) {}
}
System.out.println("ComputerCenter: 厂商送来一块显卡。");
videoN++;
VIDEO.notify();//----------------------------唤醒消费者消费
}
}
public void stockMd() {
synchronized(MAINB) {
if(MainbN >= 20) {
System.out.println("ComputerCenter: the MB storage is MAX");
try {MAINB.wait();} catch (Exception e) {}
}
System.out.println("ComputerCenter: 厂商送来一块主板。");
MainbN++;
MAINB.notify();//-----------------------------唤醒消费者消费
}
}
public void sellVd(String name) {
synchronized(VIDEO) {
if(videoN <= 0) {
System.out.println("没有显卡了,等等,马上送来!!!!!!!!!");
try {VIDEO.wait();} catch (Exception e) {}
}
System.out.println(name + " : 买走一块显卡。");
videoN--;
VIDEO.notify();//----------------------------------唤醒厂商
}
}
public void sellMd(String name) {
synchronized(MAINB) {
if(MainbN <= 0) {
System.out.println("没有主板了,等等,马上送来!!!!!!!!!!");
try {MAINB.wait();} catch (Exception e) {}
}
System.out.println(name + " : 买走一块主板。");
MainbN--;
MAINB.notify();//----------------------------------唤醒厂商
}
}
public static void main(String[] args) {
ComputerCenter MyCC = new ComputerCenter();
new customer(MyCC,"Jack").start();
new customer(MyCC,"Tom").start();
new Md_retailer(MyCC).start();
new Vd_retailer(MyCC).start();
}
}
class customer extends Thread {
private ComputerCenter cc;
private String name;
public customer(ComputerCenter cc,String name) {
this.cc = cc;
this.name = name;
}
public void run() {
while(true) {
//try {Thread.sleep(10);} catch (Exception e) {}
//顾客不断购买显卡和主板
cc.sellVd(name); cc.sellMd(name);
}
}
}
class Md_retailer extends Thread {
private ComputerCenter cc;
public Md_retailer(ComputerCenter cc) {
this.cc = cc;
}
public void run() {
while(true) {
try {Thread.sleep(10);} catch (Exception e) {}
cc.stockMd();
}
}
}
class Vd_retailer extends Thread {
private ComputerCenter cc;
public Vd_retailer(ComputerCenter cc) {
this.cc = cc;
}
public void run() {
while(true) {
try {Thread.sleep(10);} catch (Exception e) {}
cc.stockVd();
}
}
}
注释掉不同地方的 try {Thread.sleep(10);} catch (Exception e) {} 可以模拟不同的情况。
非常感谢您,我修改了一下代码,用synchronized代码块来指定唤醒地对象。但是依然有一个问题:当有2人同时在等待买显卡地时候,厂商送来一块显卡,A买完后,却会唤醒B去买。这里有逻辑错误。该怎么样改进一下呢?
其实还有有种办法解决,就是通过在wait()那里套一个while(iswaiting)来实现唤醒指定地线程。电脑城进货后,改变某个boolean值,唤醒所有线程。那些没有被改变boolean值的线程将被套在while循环里面。这样可以解决问题,但我总觉得怪怪地不自然。
------------------------------------------------------------------------------------------------------------------
问题补充:
xmind 写道
噢,对不起,我是没有考虑这个情况。
你说的那种方法应该能够实现,我等待后再判断的方法试了试,要使,你看看
Java代码
public void sellMd(String name) {
synchronized(MAINB) {
if(MainbN <= 0) {
System.out.println("没有主板了,等等,马上送来!!!!!!!!!!");
try {MAINB.wait();} catch (Exception e) {}
}
if(MainbN >0) {
System.out.println(name + " : 买走一块主板。"+MainbN);
MainbN--;
}
MAINB.notify();//----------------------------------唤醒厂商
}
}
}
谢谢您。我觉得呢,这样子看上去是可行的,但还有一点逻辑上的错误。假如A,B都在等待买显卡,此时电脑城获得一块显卡,库存显卡数为1,通知AB其中一个。假设A买到了显卡,显卡库存变为0。此时A唤醒B。B醒来后if判断显卡数不大于0,所以并没有买走显卡,但是他却被唤醒并离开了,也就是说他这次不买显卡了(他本来是想买显卡的,只不过没货,在等待)。并且他离开时通知了电脑城再进一块显卡(如果此时达到库存上线,厂商在等待消费,那么它将被B唤醒而生产显卡,导致电脑城显卡数超出库存)。
这里是不是有点逻辑上的小漏洞呢?大家探讨探讨。
------------------------------------------------------------------------------------------------------------------
问题补充:
hareamao 写道
Java代码
import java.util.ArrayDeque;
public class StockManager {
private final Object producerLock = new Object();
private final Object consumerLock = new Object();
private final int MAX_SIZE = 10;
private final ArrayDeque<Product> queue = new ArrayDeque<Product>();
public void stock(Product p) throws InterruptedException {
synchronized (producerLock) {
if (queue.size() >= MAX_SIZE) {
producerLock.wait();
}
}
synchronized (queue) {
queue.add(p);
}
synchronized (consumerLock) {
consumerLock.notify();
}
}
public synchronized Product purchase() throws InterruptedException {
synchronized (consumerLock) {
if (queue.size() <= 0) {
consumerLock.wait();
}
}
Product product = null;
synchronized (queue) {
product = queue.remove();
}
synchronized (producerLock) {
producerLock.notify();
}
return product;
}
}
lz基本的问题就是,厂商和客户等的不是同一把锁,所以要分别对待。然后就简单了。不过我的StockManager看着也不怎么对劲儿。
阁下的方法是,将StockManager分开实例化令厂商解锁时只解在自己队列上排队的顾客,从而避免了唤醒另外一条队的顾客。这样子也可以。thanks。
另外问一句,为什么阁下的代码中这么多final的?
采纳的答案
2010-07-26 hareamao (高级程序员)
没怎么写过多线程,拿来练练手,未必正确。
Java代码
public class Product {
private String name;
private int serial;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getSerial() {
return serial;
}
public void setSerial(int serial) {
this.serial = serial;
}
}
Java代码
import java.util.ArrayDeque;
public class StockManager {
private final Object producerLock = new Object();
private final Object consumerLock = new Object();
private final int MAX_SIZE = 10;
private final ArrayDeque<Product> queue = new ArrayDeque<Product>();
public void stock(Product p) throws InterruptedException {
synchronized (producerLock) {
if (queue.size() >= MAX_SIZE) {
producerLock.wait();
}
}
synchronized (queue) {
queue.add(p);
}
synchronized (consumerLock) {
consumerLock.notify();
}
}
public synchronized Product purchase() throws InterruptedException {
synchronized (consumerLock) {
if (queue.size() <= 0) {
consumerLock.wait();
}
}
Product product = null;
synchronized (queue) {
product = queue.remove();
}
synchronized (producerLock) {
producerLock.notify();
}
return product;
}
}
Java代码
import java.util.logging.Logger;
public class Producer implements Runnable{
private static final Logger log = Logger.getLogger(Producer.class.getName());
private String productName = null;
private int serial = 0;
private StockManager stockManager;
public void setProductName(String productName) {
this.productName = productName;
}
public void setStockManager(StockManager stockManager) {
this.stockManager = stockManager;
}
public Product produce() {
final Product p = new Product();
p.setName(productName);
p.setSerial(++serial);
return p;
}
@Override
public void run() {
try {
for( int i = 0; i < 20; i++) {
deliver();
}
Thread.sleep(30 * 1000);
while (true) {
deliver();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void deliver() throws InterruptedException {
final long s = System.currentTimeMillis();
final Product product = produce();
stockManager.stock(product);
final long time = System.currentTimeMillis() - s;
if (time > 10) {
log.info(product.getName() + ", No. " +
product.getSerial() + " took " +
time + " milli seconds to finish." );
}
}
}
Java代码
import java.util.logging.Logger;
public class Consumer implements Runnable {
private static final Logger log = Logger.getLogger(Consumer.class.getName());
private String name;
private StockManager[] stockManagers;
public void setName(String name) {
this.name = name;
}
public void setStockManagers(StockManager[] stockManagers) {
this.stockManagers = stockManagers;
}
@Override
public void run() {
for (int i = 0; i < 50; i++) {
final double v = Math.random() * stockManagers.length;
final int k = (int) Math.floor(v);
try {
final long s = System.currentTimeMillis();
final Product product = stockManagers[k].purchase();
final long time = System.currentTimeMillis() - s;
String l = "";
if (time > 10) {
l += "after " + time + " milli seconds of waiting, ";
}
l += (name + " bought product " + product.getName()
+ ", serial No. " + product.getSerial());
log.info(l);
} catch (InterruptedException e) {
e.printStackTrace();
break;
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
break;
}
}
}
}
Java代码
public class Mall {
public static void main(String[] args) {
final StockManager mb = new StockManager();
final Producer pmb = new Producer();
pmb.setProductName("Motherboard");
pmb.setStockManager(mb);
final StockManager vd = new StockManager();
final Producer pvd = new Producer();
pvd.setProductName("Video Card");
pvd.setStockManager(vd);
final StockManager[] stockManagers = new StockManager[2];
stockManagers[0] = mb;
stockManagers[1] = vd;
final Consumer c1 = new Consumer();
c1.setName("C1");
c1.setStockManagers(stockManagers);
final Consumer c2 = new Consumer();
c2.setName("C2");
c2.setStockManagers(stockManagers);
new Thread(c1).start();
new Thread(c2).start();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(pmb).start();
new Thread(pvd).start();
}
}
提问者对于答案的评价:
解决办法之一.
问题答案可能在这里 → 寻找更多解答
java生产者消费者经典问题
Java 关于线程同步的问题
java多线程 消费者-生产者
我有一个关于多线程编码的问题..
一段关于线程的代码 请教
其他回答
1.消费者由生产唤醒,每次唤醒队列中的一个,A买完就走,不要多管闲事
2.不同的产品在不同的队列中,不要排别人的队
3.4.同2
qinglangee (资深程序员) 2010-07-26
主要问题是 显卡 没了,等显卡送来,主板没了等主板送来。
不能人家来买显卡的,你进来一个主板也通知人家来买。
写了个例子,你看看。
Java代码
class ComputerCenter {
private static Object VIDEO = new Object();
private static Object MAINB = new Object();
private static Integer videoN = 10;
private static Integer MainbN = 10;
public void stockVd() {
synchronized(VIDEO) {
if(videoN >= 20) {
System.out.println("ComputerCenter: the VC storage is MAX");
try {VIDEO.wait();} catch (Exception e) {}
}
System.out.println("ComputerCenter: 厂商送来一块显卡。");
videoN++;
VIDEO.notify();//----------------------------唤醒消费者消费
}
}
public void stockMd() {
synchronized(MAINB) {
if(MainbN >= 20) {
System.out.println("ComputerCenter: the MB storage is MAX");
try {MAINB.wait();} catch (Exception e) {}
}
System.out.println("ComputerCenter: 厂商送来一块主板。");
MainbN++;
MAINB.notify();//-----------------------------唤醒消费者消费
}
}
public void sellVd(String name) {
synchronized(VIDEO) {
if(videoN <= 0) {
System.out.println("没有显卡了,等等,马上送来!!!!!!!!!");
try {VIDEO.wait();} catch (Exception e) {}
}
System.out.println(name + " : 买走一块显卡。");
videoN--;
VIDEO.notify();//----------------------------------唤醒厂商
}
}
public void sellMd(String name) {
synchronized(MAINB) {
if(MainbN <= 0) {
System.out.println("没有主板了,等等,马上送来!!!!!!!!!!");
try {MAINB.wait();} catch (Exception e) {}
}
System.out.println(name + " : 买走一块主板。");
MainbN--;
MAINB.notify();//----------------------------------唤醒厂商
}
}
public static void main(String[] args) {
ComputerCenter MyCC = new ComputerCenter();
new customer(MyCC,"Jack").start();
new customer(MyCC,"Tom").start();
new Md_retailer(MyCC).start();
new Vd_retailer(MyCC).start();
}
}
class customer extends Thread {
private ComputerCenter cc;
private String name;
public customer(ComputerCenter cc,String name) {
this.cc = cc;
this.name = name;
}
public void run() {
while(true) {
//try {Thread.sleep(10);} catch (Exception e) {}
//顾客不断购买显卡和主板
cc.sellVd(name); cc.sellMd(name);
}
}
}
class Md_retailer extends Thread {
private ComputerCenter cc;
public Md_retailer(ComputerCenter cc) {
this.cc = cc;
}
public void run() {
while(true) {
try {Thread.sleep(10);} catch (Exception e) {}
cc.stockMd();
}
}
}
class Vd_retailer extends Thread {
private ComputerCenter cc;
public Vd_retailer(ComputerCenter cc) {
this.cc = cc;
}
public void run() {
while(true) {
try {Thread.sleep(10);} catch (Exception e) {}
cc.stockVd();
}
}
}
注释掉不同地方的 try {Thread.sleep(10);} catch (Exception e) {} 可以模拟不同的情况。
xmind (中级程序员) 2010-07-26
噢,对不起,我是没有考虑这个情况。
你说的那种方法应该能够实现,我等待后再判断的方法试了试,要使,你看看
Java代码
class ComputerCenter {
private static Object VIDEO = new Object();
private static Object MAINB = new Object();
private static Integer videoN = 10;
private static Integer MainbN = 10;
public void stockVd() {
synchronized(VIDEO) {
if(videoN >= 20) {
System.out.println("ComputerCenter: the VC storage is MAX");
try {VIDEO.wait();} catch (Exception e) {}
}
videoN++;
System.out.println("ComputerCenter: 厂商送来一块显卡。" + videoN);
VIDEO.notify();//----------------------------唤醒消费者消费
}
}
public void stockMd() {
synchronized(MAINB) {
if(MainbN >= 20) {
System.out.println("ComputerCenter: the MB storage is MAX");
try {MAINB.wait();} catch (Exception e) {}
}
MainbN++;
System.out.println("ComputerCenter: 厂商送来一块主板。"+MainbN);
MAINB.notify();//-----------------------------唤醒消费者消费
}
}
public void sellVd(String name) {
synchronized(VIDEO) {
if(videoN <= 0) {
System.out.println("没有显卡了,等等,马上送来!!!!!!!!!");
try {VIDEO.wait();} catch (Exception e) {}
}
if(videoN >0) {
System.out.println(name + " : 买走一块显卡。"+videoN);
videoN--;
}
VIDEO.notify();//----------------------------------唤醒厂商
}
}
public void sellMd(String name) {
synchronized(MAINB) {
if(MainbN <= 0) {
System.out.println("没有主板了,等等,马上送来!!!!!!!!!!");
try {MAINB.wait();} catch (Exception e) {}
}
if(MainbN >0) {
System.out.println(name + " : 买走一块主板。"+MainbN);
MainbN--;
}
MAINB.notify();//----------------------------------唤醒厂商
}
}
public static void main(String[] args) {
ComputerCenter MyCC = new ComputerCenter();
new customer(MyCC,"Jack").start();
new customer(MyCC,"Tom").start();
new Md_retailer(MyCC).start();
new Vd_retailer(MyCC).start();
}
}
class customer extends Thread {
private ComputerCenter cc;
private String name;
public customer(ComputerCenter cc,String name) {
this.cc = cc;
this.name = name;
}
public void run() {
while(true) {
//try {Thread.sleep(10);} catch (Exception e) {}
//顾客不断购买显卡和主板
cc.sellVd(name); cc.sellMd(name);
}
}
}
class Md_retailer extends Thread {
private ComputerCenter cc;
public Md_retailer(ComputerCenter cc) {
this.cc = cc;
}
public void run() {
while(true) {
try {Thread.sleep(10);} catch (Exception e) {}
cc.stockMd();
}
}
}
class Vd_retailer extends Thread {
private ComputerCenter cc;
public Vd_retailer(ComputerCenter cc) {
this.cc = cc;
}
public void run() {
while(true) {
try {Thread.sleep(10);} catch (Exception e) {}
cc.stockVd();
}
}
}
xmind (中级程序员) 2010-07-26
恩,是有点儿,这样你看行不行,也就是顾客在买的时候,如果没有等待,买完后也不通知。电脑城在进货满之后不等待(或者sleep也行,让出cpu,现实中像是卖一段时间在进货),没进一个货就通知一声,只通知一个顾客。
Java代码
class ComputerCenter {
private static Object VIDEO = new Object();
private static Object MAINB = new Object();
private static Integer videoN = 10;
private static Integer MainbN = 10;
public void stockVd() {
synchronized(VIDEO) {
if(videoN >= 20) {
System.out.println("ComputerCenter: the VC storage is MAX");
} else {
videoN++;
System.out.println("ComputerCenter: 厂商送来一块显卡。" + videoN);
VIDEO.notify();//----------------------------唤醒消费者消费
}
}
}
public void stockMd() {
synchronized(MAINB) {
if(MainbN >= 20) {
System.out.println("ComputerCenter: the MB storage is MAX");
} else {
MainbN++;
System.out.println("ComputerCenter: 厂商送来一块主板。"+MainbN);
MAINB.notify();//-----------------------------唤醒消费者消费
}
}
}
public void sellVd(String name) {
synchronized(VIDEO) {
if(videoN <= 0) {
System.out.println("没有显卡了,等等,马上送来!!!!!!!!!");
try {VIDEO.wait();} catch (Exception e) {}
}
System.out.println(name + " : 买走一块显卡。"+videoN);
videoN--;
}
}
public void sellMd(String name) {
synchronized(MAINB) {
if(MainbN <= 0) {
System.out.println("没有主板了,等等,马上送来!!!!!!!!!!");
try {MAINB.wait();} catch (Exception e) {}
}
System.out.println(name + " : 买走一块主板。"+MainbN);
MainbN--;
}
}
public static void main(String[] args) {
ComputerCenter MyCC = new ComputerCenter();
new customer(MyCC,"Jack").start();
new customer(MyCC,"Tom").start();
new Md_retailer(MyCC).start();
new Vd_retailer(MyCC).start();
}
}
class customer extends Thread {
private ComputerCenter cc;
private String name;
public customer(ComputerCenter cc,String name) {
this.cc = cc;
this.name = name;
}
public void run() {
while(true) {
//try {Thread.sleep(10);} catch (Exception e) {}
//顾客不断购买显卡和主板
cc.sellVd(name); cc.sellMd(name);
}
}
}
class Md_retailer extends Thread {
private ComputerCenter cc;
public Md_retailer(ComputerCenter cc) {
this.cc = cc;
}
public void run() {
while(true) {
try {Thread.sleep(10);} catch (Exception e) {}
cc.stockMd();
}
}
}
class Vd_retailer extends Thread {
private ComputerCenter cc;
public Vd_retailer(ComputerCenter cc) {
this.cc = cc;
}
public void run() {
while(true) {
try {Thread.sleep(10);} catch (Exception e) {}
cc.stockVd();
}
}
}
xmind (中级程序员) 2010-07-26
lz基本的问题就是,厂商和客户等的不是同一把锁,所以要分别对待。然后就简单了。不过我的StockManager看着也不怎么对劲儿。
代码有点长,主要部分如下所述:
有三方:厂家,电脑城,顾客
厂家2个,一个生产主板,一个生产显卡。
顾客有2个,他们各自不断购买主板和显卡。
电脑城有一个,卖显卡和主板。
限于篇幅问题,摘录主要代码如下:
--------------------------厂家类---------------------------------------
Java代码
public class Mainboardretailer implements Runnable// 主板厂家
{
public void run()
{
while(true)
{
电脑城.stockMainboard(deliverMB("MSI"));//不断向电脑城供货
}
}
public Mainboard deliverMB(String 主板名)
{
return 主板;
}
}
public class Videocardretailer implements Runnable// 显卡厂家
{
public void run()
{
while(true)
{
电脑城.stockVideocard(deliverVC("ATI"));//不断向电脑城供货
}
}
public videocard deliverMB(String 显卡名)
{
return 显卡;
}
}
-------------------------------------顾客类-------------------------------------------
Java代码
public class customer implements Runnable
{
public void run()
{
while(true)
{
buyVC("ATI");
//顾客不断购买显卡和主板
buyMB("MSI");
}
}
}
-----------------------------电脑城类-----------------------------------------
Java代码
public class ComputerCenter
{
int MAXVCSTORE = 100;//货仓容量
int MAXMBSTORE = 100;//货仓容量
private static LinkedList<Videocard> VideocardQty = new LinkedList<Videocard>();//显卡货仓
private static LinkedList<Mainboard> MainboardQty = new LinkedList<Mainboard>();//主板货仓
public synchronized void stockVideocard(Videocard VCname)
{
if(VideocardQty.size() >= MAXVCSTORE)
{
System.out.println("ComputerCenter: the VC storage is MAX");
try
{
wait();//---------------------当存货过多时。通知厂商等待。
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
VideocardQty.add(VCname);
notify();//----------------------------唤醒消费者消费
}
public synchronized void stockMainboard(Mainboard MBname)
{
if(MainboardQty.size() >= MAXVCSTORE)
{
System.out.println("ComputerCenter: the MB storage is MAX");
try
{
wait();//----------------------当存货过多时。通知厂商等待。
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
MainboardQty.add(MBname);
notify();//-----------------------------唤醒消费者消费
}
public synchronized Videocard sellVideocard(String VCname)
{
if(VideocardQty.size() <= 0)
{
try
{
wait();//-----------------没有存货时,通知消费者等待
}catch(Exception e)
{
e.printStackTrace();
}
}
notify();//----------------------------------唤醒厂商
return MyVideocard;
}
public synchronized Mainboard sellMainboard(String MBname)
{
if(MainboardQty.size() <= 0)
{
try
{
wait();//-----------------没有存货时,通知消费者等待
}catch(Exception e)
{
e.printStackTrace();
}
}
notify();//----------------------------------唤醒厂商
return MyMainboard;
}
public static void main(String[] args)
{
ComputerCenter MyCC = new ComputerCenter();
new customer(MyCC,"Jack").start();
new customer(MyCC,"Tom").start();
new Mainboardretailer(MyCC).start();
new Videocardretailer(MyCC).start();
}
}
现在出现了这样的一个问题:
1.如果有两个消费者同时等待,厂家生产后唤醒其中消费者A,消费者A购买完毕后会唤醒消费者B--不合逻辑。
2.如果购买显卡地消费者A在等待,电脑城从主板厂商进货了主板以后会唤醒消费者A。同样的情况也发生在购买主板的消费者B身上。
3.如果两家厂商在等待消费者购买商品,此时消费者A购买了主板,货仓主板数量-1,然后有可能唤醒显卡厂商而没有唤醒主板厂商进行生产。
4.如果两家厂商正在等待消费者购买商品,此时显卡厂商被唤醒后,可能立刻唤醒主板厂商生产主板,令到商品数量超出仓库上限。
我想,有没有什么办法,可以指定唤醒某个线程?如果可以,那问题就容易解决了。
------------------------------------------------------------------------------------------------------------------
问题补充:
xmind 写道
主要问题是 显卡 没了,等显卡送来,主板没了等主板送来。
不能人家来买显卡的,你进来一个主板也通知人家来买。
写了个例子,你看看。
Java代码
class ComputerCenter {
private static Object VIDEO = new Object();
private static Object MAINB = new Object();
private static Integer videoN = 10;
private static Integer MainbN = 10;
public void stockVd() {
synchronized(VIDEO) {
if(videoN >= 20) {
System.out.println("ComputerCenter: the VC storage is MAX");
try {VIDEO.wait();} catch (Exception e) {}
}
System.out.println("ComputerCenter: 厂商送来一块显卡。");
videoN++;
VIDEO.notify();//----------------------------唤醒消费者消费
}
}
public void stockMd() {
synchronized(MAINB) {
if(MainbN >= 20) {
System.out.println("ComputerCenter: the MB storage is MAX");
try {MAINB.wait();} catch (Exception e) {}
}
System.out.println("ComputerCenter: 厂商送来一块主板。");
MainbN++;
MAINB.notify();//-----------------------------唤醒消费者消费
}
}
public void sellVd(String name) {
synchronized(VIDEO) {
if(videoN <= 0) {
System.out.println("没有显卡了,等等,马上送来!!!!!!!!!");
try {VIDEO.wait();} catch (Exception e) {}
}
System.out.println(name + " : 买走一块显卡。");
videoN--;
VIDEO.notify();//----------------------------------唤醒厂商
}
}
public void sellMd(String name) {
synchronized(MAINB) {
if(MainbN <= 0) {
System.out.println("没有主板了,等等,马上送来!!!!!!!!!!");
try {MAINB.wait();} catch (Exception e) {}
}
System.out.println(name + " : 买走一块主板。");
MainbN--;
MAINB.notify();//----------------------------------唤醒厂商
}
}
public static void main(String[] args) {
ComputerCenter MyCC = new ComputerCenter();
new customer(MyCC,"Jack").start();
new customer(MyCC,"Tom").start();
new Md_retailer(MyCC).start();
new Vd_retailer(MyCC).start();
}
}
class customer extends Thread {
private ComputerCenter cc;
private String name;
public customer(ComputerCenter cc,String name) {
this.cc = cc;
this.name = name;
}
public void run() {
while(true) {
//try {Thread.sleep(10);} catch (Exception e) {}
//顾客不断购买显卡和主板
cc.sellVd(name); cc.sellMd(name);
}
}
}
class Md_retailer extends Thread {
private ComputerCenter cc;
public Md_retailer(ComputerCenter cc) {
this.cc = cc;
}
public void run() {
while(true) {
try {Thread.sleep(10);} catch (Exception e) {}
cc.stockMd();
}
}
}
class Vd_retailer extends Thread {
private ComputerCenter cc;
public Vd_retailer(ComputerCenter cc) {
this.cc = cc;
}
public void run() {
while(true) {
try {Thread.sleep(10);} catch (Exception e) {}
cc.stockVd();
}
}
}
注释掉不同地方的 try {Thread.sleep(10);} catch (Exception e) {} 可以模拟不同的情况。
非常感谢您,我修改了一下代码,用synchronized代码块来指定唤醒地对象。但是依然有一个问题:当有2人同时在等待买显卡地时候,厂商送来一块显卡,A买完后,却会唤醒B去买。这里有逻辑错误。该怎么样改进一下呢?
其实还有有种办法解决,就是通过在wait()那里套一个while(iswaiting)来实现唤醒指定地线程。电脑城进货后,改变某个boolean值,唤醒所有线程。那些没有被改变boolean值的线程将被套在while循环里面。这样可以解决问题,但我总觉得怪怪地不自然。
------------------------------------------------------------------------------------------------------------------
问题补充:
xmind 写道
噢,对不起,我是没有考虑这个情况。
你说的那种方法应该能够实现,我等待后再判断的方法试了试,要使,你看看
Java代码
public void sellMd(String name) {
synchronized(MAINB) {
if(MainbN <= 0) {
System.out.println("没有主板了,等等,马上送来!!!!!!!!!!");
try {MAINB.wait();} catch (Exception e) {}
}
if(MainbN >0) {
System.out.println(name + " : 买走一块主板。"+MainbN);
MainbN--;
}
MAINB.notify();//----------------------------------唤醒厂商
}
}
}
谢谢您。我觉得呢,这样子看上去是可行的,但还有一点逻辑上的错误。假如A,B都在等待买显卡,此时电脑城获得一块显卡,库存显卡数为1,通知AB其中一个。假设A买到了显卡,显卡库存变为0。此时A唤醒B。B醒来后if判断显卡数不大于0,所以并没有买走显卡,但是他却被唤醒并离开了,也就是说他这次不买显卡了(他本来是想买显卡的,只不过没货,在等待)。并且他离开时通知了电脑城再进一块显卡(如果此时达到库存上线,厂商在等待消费,那么它将被B唤醒而生产显卡,导致电脑城显卡数超出库存)。
这里是不是有点逻辑上的小漏洞呢?大家探讨探讨。
------------------------------------------------------------------------------------------------------------------
问题补充:
hareamao 写道
Java代码
import java.util.ArrayDeque;
public class StockManager {
private final Object producerLock = new Object();
private final Object consumerLock = new Object();
private final int MAX_SIZE = 10;
private final ArrayDeque<Product> queue = new ArrayDeque<Product>();
public void stock(Product p) throws InterruptedException {
synchronized (producerLock) {
if (queue.size() >= MAX_SIZE) {
producerLock.wait();
}
}
synchronized (queue) {
queue.add(p);
}
synchronized (consumerLock) {
consumerLock.notify();
}
}
public synchronized Product purchase() throws InterruptedException {
synchronized (consumerLock) {
if (queue.size() <= 0) {
consumerLock.wait();
}
}
Product product = null;
synchronized (queue) {
product = queue.remove();
}
synchronized (producerLock) {
producerLock.notify();
}
return product;
}
}
lz基本的问题就是,厂商和客户等的不是同一把锁,所以要分别对待。然后就简单了。不过我的StockManager看着也不怎么对劲儿。
阁下的方法是,将StockManager分开实例化令厂商解锁时只解在自己队列上排队的顾客,从而避免了唤醒另外一条队的顾客。这样子也可以。thanks。
另外问一句,为什么阁下的代码中这么多final的?
采纳的答案
2010-07-26 hareamao (高级程序员)
没怎么写过多线程,拿来练练手,未必正确。
Java代码
public class Product {
private String name;
private int serial;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getSerial() {
return serial;
}
public void setSerial(int serial) {
this.serial = serial;
}
}
Java代码
import java.util.ArrayDeque;
public class StockManager {
private final Object producerLock = new Object();
private final Object consumerLock = new Object();
private final int MAX_SIZE = 10;
private final ArrayDeque<Product> queue = new ArrayDeque<Product>();
public void stock(Product p) throws InterruptedException {
synchronized (producerLock) {
if (queue.size() >= MAX_SIZE) {
producerLock.wait();
}
}
synchronized (queue) {
queue.add(p);
}
synchronized (consumerLock) {
consumerLock.notify();
}
}
public synchronized Product purchase() throws InterruptedException {
synchronized (consumerLock) {
if (queue.size() <= 0) {
consumerLock.wait();
}
}
Product product = null;
synchronized (queue) {
product = queue.remove();
}
synchronized (producerLock) {
producerLock.notify();
}
return product;
}
}
Java代码
import java.util.logging.Logger;
public class Producer implements Runnable{
private static final Logger log = Logger.getLogger(Producer.class.getName());
private String productName = null;
private int serial = 0;
private StockManager stockManager;
public void setProductName(String productName) {
this.productName = productName;
}
public void setStockManager(StockManager stockManager) {
this.stockManager = stockManager;
}
public Product produce() {
final Product p = new Product();
p.setName(productName);
p.setSerial(++serial);
return p;
}
@Override
public void run() {
try {
for( int i = 0; i < 20; i++) {
deliver();
}
Thread.sleep(30 * 1000);
while (true) {
deliver();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void deliver() throws InterruptedException {
final long s = System.currentTimeMillis();
final Product product = produce();
stockManager.stock(product);
final long time = System.currentTimeMillis() - s;
if (time > 10) {
log.info(product.getName() + ", No. " +
product.getSerial() + " took " +
time + " milli seconds to finish." );
}
}
}
Java代码
import java.util.logging.Logger;
public class Consumer implements Runnable {
private static final Logger log = Logger.getLogger(Consumer.class.getName());
private String name;
private StockManager[] stockManagers;
public void setName(String name) {
this.name = name;
}
public void setStockManagers(StockManager[] stockManagers) {
this.stockManagers = stockManagers;
}
@Override
public void run() {
for (int i = 0; i < 50; i++) {
final double v = Math.random() * stockManagers.length;
final int k = (int) Math.floor(v);
try {
final long s = System.currentTimeMillis();
final Product product = stockManagers[k].purchase();
final long time = System.currentTimeMillis() - s;
String l = "";
if (time > 10) {
l += "after " + time + " milli seconds of waiting, ";
}
l += (name + " bought product " + product.getName()
+ ", serial No. " + product.getSerial());
log.info(l);
} catch (InterruptedException e) {
e.printStackTrace();
break;
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
break;
}
}
}
}
Java代码
public class Mall {
public static void main(String[] args) {
final StockManager mb = new StockManager();
final Producer pmb = new Producer();
pmb.setProductName("Motherboard");
pmb.setStockManager(mb);
final StockManager vd = new StockManager();
final Producer pvd = new Producer();
pvd.setProductName("Video Card");
pvd.setStockManager(vd);
final StockManager[] stockManagers = new StockManager[2];
stockManagers[0] = mb;
stockManagers[1] = vd;
final Consumer c1 = new Consumer();
c1.setName("C1");
c1.setStockManagers(stockManagers);
final Consumer c2 = new Consumer();
c2.setName("C2");
c2.setStockManagers(stockManagers);
new Thread(c1).start();
new Thread(c2).start();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(pmb).start();
new Thread(pvd).start();
}
}
提问者对于答案的评价:
解决办法之一.
问题答案可能在这里 → 寻找更多解答
java生产者消费者经典问题
Java 关于线程同步的问题
java多线程 消费者-生产者
我有一个关于多线程编码的问题..
一段关于线程的代码 请教
其他回答
1.消费者由生产唤醒,每次唤醒队列中的一个,A买完就走,不要多管闲事
2.不同的产品在不同的队列中,不要排别人的队
3.4.同2
qinglangee (资深程序员) 2010-07-26
主要问题是 显卡 没了,等显卡送来,主板没了等主板送来。
不能人家来买显卡的,你进来一个主板也通知人家来买。
写了个例子,你看看。
Java代码
class ComputerCenter {
private static Object VIDEO = new Object();
private static Object MAINB = new Object();
private static Integer videoN = 10;
private static Integer MainbN = 10;
public void stockVd() {
synchronized(VIDEO) {
if(videoN >= 20) {
System.out.println("ComputerCenter: the VC storage is MAX");
try {VIDEO.wait();} catch (Exception e) {}
}
System.out.println("ComputerCenter: 厂商送来一块显卡。");
videoN++;
VIDEO.notify();//----------------------------唤醒消费者消费
}
}
public void stockMd() {
synchronized(MAINB) {
if(MainbN >= 20) {
System.out.println("ComputerCenter: the MB storage is MAX");
try {MAINB.wait();} catch (Exception e) {}
}
System.out.println("ComputerCenter: 厂商送来一块主板。");
MainbN++;
MAINB.notify();//-----------------------------唤醒消费者消费
}
}
public void sellVd(String name) {
synchronized(VIDEO) {
if(videoN <= 0) {
System.out.println("没有显卡了,等等,马上送来!!!!!!!!!");
try {VIDEO.wait();} catch (Exception e) {}
}
System.out.println(name + " : 买走一块显卡。");
videoN--;
VIDEO.notify();//----------------------------------唤醒厂商
}
}
public void sellMd(String name) {
synchronized(MAINB) {
if(MainbN <= 0) {
System.out.println("没有主板了,等等,马上送来!!!!!!!!!!");
try {MAINB.wait();} catch (Exception e) {}
}
System.out.println(name + " : 买走一块主板。");
MainbN--;
MAINB.notify();//----------------------------------唤醒厂商
}
}
public static void main(String[] args) {
ComputerCenter MyCC = new ComputerCenter();
new customer(MyCC,"Jack").start();
new customer(MyCC,"Tom").start();
new Md_retailer(MyCC).start();
new Vd_retailer(MyCC).start();
}
}
class customer extends Thread {
private ComputerCenter cc;
private String name;
public customer(ComputerCenter cc,String name) {
this.cc = cc;
this.name = name;
}
public void run() {
while(true) {
//try {Thread.sleep(10);} catch (Exception e) {}
//顾客不断购买显卡和主板
cc.sellVd(name); cc.sellMd(name);
}
}
}
class Md_retailer extends Thread {
private ComputerCenter cc;
public Md_retailer(ComputerCenter cc) {
this.cc = cc;
}
public void run() {
while(true) {
try {Thread.sleep(10);} catch (Exception e) {}
cc.stockMd();
}
}
}
class Vd_retailer extends Thread {
private ComputerCenter cc;
public Vd_retailer(ComputerCenter cc) {
this.cc = cc;
}
public void run() {
while(true) {
try {Thread.sleep(10);} catch (Exception e) {}
cc.stockVd();
}
}
}
注释掉不同地方的 try {Thread.sleep(10);} catch (Exception e) {} 可以模拟不同的情况。
xmind (中级程序员) 2010-07-26
噢,对不起,我是没有考虑这个情况。
你说的那种方法应该能够实现,我等待后再判断的方法试了试,要使,你看看
Java代码
class ComputerCenter {
private static Object VIDEO = new Object();
private static Object MAINB = new Object();
private static Integer videoN = 10;
private static Integer MainbN = 10;
public void stockVd() {
synchronized(VIDEO) {
if(videoN >= 20) {
System.out.println("ComputerCenter: the VC storage is MAX");
try {VIDEO.wait();} catch (Exception e) {}
}
videoN++;
System.out.println("ComputerCenter: 厂商送来一块显卡。" + videoN);
VIDEO.notify();//----------------------------唤醒消费者消费
}
}
public void stockMd() {
synchronized(MAINB) {
if(MainbN >= 20) {
System.out.println("ComputerCenter: the MB storage is MAX");
try {MAINB.wait();} catch (Exception e) {}
}
MainbN++;
System.out.println("ComputerCenter: 厂商送来一块主板。"+MainbN);
MAINB.notify();//-----------------------------唤醒消费者消费
}
}
public void sellVd(String name) {
synchronized(VIDEO) {
if(videoN <= 0) {
System.out.println("没有显卡了,等等,马上送来!!!!!!!!!");
try {VIDEO.wait();} catch (Exception e) {}
}
if(videoN >0) {
System.out.println(name + " : 买走一块显卡。"+videoN);
videoN--;
}
VIDEO.notify();//----------------------------------唤醒厂商
}
}
public void sellMd(String name) {
synchronized(MAINB) {
if(MainbN <= 0) {
System.out.println("没有主板了,等等,马上送来!!!!!!!!!!");
try {MAINB.wait();} catch (Exception e) {}
}
if(MainbN >0) {
System.out.println(name + " : 买走一块主板。"+MainbN);
MainbN--;
}
MAINB.notify();//----------------------------------唤醒厂商
}
}
public static void main(String[] args) {
ComputerCenter MyCC = new ComputerCenter();
new customer(MyCC,"Jack").start();
new customer(MyCC,"Tom").start();
new Md_retailer(MyCC).start();
new Vd_retailer(MyCC).start();
}
}
class customer extends Thread {
private ComputerCenter cc;
private String name;
public customer(ComputerCenter cc,String name) {
this.cc = cc;
this.name = name;
}
public void run() {
while(true) {
//try {Thread.sleep(10);} catch (Exception e) {}
//顾客不断购买显卡和主板
cc.sellVd(name); cc.sellMd(name);
}
}
}
class Md_retailer extends Thread {
private ComputerCenter cc;
public Md_retailer(ComputerCenter cc) {
this.cc = cc;
}
public void run() {
while(true) {
try {Thread.sleep(10);} catch (Exception e) {}
cc.stockMd();
}
}
}
class Vd_retailer extends Thread {
private ComputerCenter cc;
public Vd_retailer(ComputerCenter cc) {
this.cc = cc;
}
public void run() {
while(true) {
try {Thread.sleep(10);} catch (Exception e) {}
cc.stockVd();
}
}
}
xmind (中级程序员) 2010-07-26
恩,是有点儿,这样你看行不行,也就是顾客在买的时候,如果没有等待,买完后也不通知。电脑城在进货满之后不等待(或者sleep也行,让出cpu,现实中像是卖一段时间在进货),没进一个货就通知一声,只通知一个顾客。
Java代码
class ComputerCenter {
private static Object VIDEO = new Object();
private static Object MAINB = new Object();
private static Integer videoN = 10;
private static Integer MainbN = 10;
public void stockVd() {
synchronized(VIDEO) {
if(videoN >= 20) {
System.out.println("ComputerCenter: the VC storage is MAX");
} else {
videoN++;
System.out.println("ComputerCenter: 厂商送来一块显卡。" + videoN);
VIDEO.notify();//----------------------------唤醒消费者消费
}
}
}
public void stockMd() {
synchronized(MAINB) {
if(MainbN >= 20) {
System.out.println("ComputerCenter: the MB storage is MAX");
} else {
MainbN++;
System.out.println("ComputerCenter: 厂商送来一块主板。"+MainbN);
MAINB.notify();//-----------------------------唤醒消费者消费
}
}
}
public void sellVd(String name) {
synchronized(VIDEO) {
if(videoN <= 0) {
System.out.println("没有显卡了,等等,马上送来!!!!!!!!!");
try {VIDEO.wait();} catch (Exception e) {}
}
System.out.println(name + " : 买走一块显卡。"+videoN);
videoN--;
}
}
public void sellMd(String name) {
synchronized(MAINB) {
if(MainbN <= 0) {
System.out.println("没有主板了,等等,马上送来!!!!!!!!!!");
try {MAINB.wait();} catch (Exception e) {}
}
System.out.println(name + " : 买走一块主板。"+MainbN);
MainbN--;
}
}
public static void main(String[] args) {
ComputerCenter MyCC = new ComputerCenter();
new customer(MyCC,"Jack").start();
new customer(MyCC,"Tom").start();
new Md_retailer(MyCC).start();
new Vd_retailer(MyCC).start();
}
}
class customer extends Thread {
private ComputerCenter cc;
private String name;
public customer(ComputerCenter cc,String name) {
this.cc = cc;
this.name = name;
}
public void run() {
while(true) {
//try {Thread.sleep(10);} catch (Exception e) {}
//顾客不断购买显卡和主板
cc.sellVd(name); cc.sellMd(name);
}
}
}
class Md_retailer extends Thread {
private ComputerCenter cc;
public Md_retailer(ComputerCenter cc) {
this.cc = cc;
}
public void run() {
while(true) {
try {Thread.sleep(10);} catch (Exception e) {}
cc.stockMd();
}
}
}
class Vd_retailer extends Thread {
private ComputerCenter cc;
public Vd_retailer(ComputerCenter cc) {
this.cc = cc;
}
public void run() {
while(true) {
try {Thread.sleep(10);} catch (Exception e) {}
cc.stockVd();
}
}
}
xmind (中级程序员) 2010-07-26
lz基本的问题就是,厂商和客户等的不是同一把锁,所以要分别对待。然后就简单了。不过我的StockManager看着也不怎么对劲儿。
发表评论
-
子线程循环10次,接着主线程循环100,接着又回到子线程循环10次,接着再回到主线程又循环100,如此循环50次,请写出程序。
2013-04-15 14:00 1234public class ThreadTest { ... -
java并发包(java.util.concurrent)
2013-03-26 23:46 1988java并发包(java.util.concurrent) ... -
java 死锁及解决
2013-03-19 22:54 930url:http://leowzy.iteye.com/bl ... -
断点续传的原理
2013-03-08 12:32 1136url:http://www.cnblogs.com/Kil ... -
《java并发编程实践》读书笔记
2012-08-21 23:07 972文章链接:http://www.iteye.com/blogs ... -
ThreadLocal详解
2012-06-27 23:47 935文章链接: http://www.iteye.com/top ... -
多线程并发(java编程思想笔记)
2012-06-25 23:50 24251.Executor,java.util.concurr ... -
多线程例题(空中网)
2012-06-17 19:16 998文章链接:http://blog.csdn ... -
ArrayBlockingQueue(阻塞队列)
2012-06-17 19:00 1535package cn.itcast.day3.thread; ... -
多线程笔记(黑马)
2012-06-17 18:59 9941.多线程范围内间的线 ... -
设计缓冲系统(多线程)
2012-06-17 18:57 1026package cn.itcast.day3.thread; ... -
Java多线程与并发库高级应用(传智播客)
2012-06-13 15:14 3733------------------------------- ... -
多线程断点续传下载
2012-06-05 20:58 1753package cn.itcast.net.downlo ... -
java多线程断点续传
2012-06-05 10:00 1322在android下面的断点 ... -
多线程高新(黑马程序员)
2012-03-30 16:23 1206------------------------------- ... -
生产者/消费者JAVA多线程
2012-03-28 09:58 1030文章链接:http://blog.csdn.net/bnuch ... -
主线程与子线程之间通讯, 子线程与子线程之间的通讯 Java
2012-03-17 19:19 5350线程之间的通讯可以有两种方法. 一.利用全局变量. 大家都可 ... -
理解多线程
2011-09-27 17:40 841一、理解多线程 多 ...
相关推荐
JAVA主线程等待子线程执行完毕再执行[参照].pdf
NULL 博文链接:https://zhaoningbo.iteye.com/blog/1158225
主线程如何捕获子线程的异常---马克-to-win java视频的介绍
自己学着编写的一个JAVA多线程程序,该程序实现的功能是:在主线程main中创建两个子线程,A和B,线程A先运行,再运行B线程,当两个子线程都运行完毕后,才运行主线程,并最终结束整个程序的运行。 希望该程序对初学...
java 子线程通过观察者模式通知主线程
非常实用不解释,用了才知道 个人收藏的一部分资料将陆续给大家上传
子线程更新主线程数据(再谈多线程)
子线程任务发生异常,主线程事务如何回滚
java多线程知识点,源代码案例,代码案例中包括如何创建线程,主线程,线程优先级,线程组,线程同步,死锁,线程间的通信知识点
Java多线程--让主线程等待所有子线程执行完毕
java 多线程 其实就是每个线程都拥有自己的内存空间,多线程之间的通信,比例A线程修改了主内存(main方法的线程)变量,需要把A线程修改的结果同步到主线程中,这时B线程再从主线程获取该变量的值,这样就实现了...
我们知道Android卡顿主要是主线程中有耗时操作导致的,那么我们怎么能方便快捷的获取主线程中的所有耗时方法执行时间呢?今天我们来介绍两个方案 方案一:利用Looper.java中loop()方法的logging.print的特殊关键字...
编写一个Java应用程序,在主线程中再创建2个线程,要求线程经历4种状态:新建、运行、中断和死亡
数据量很大百万条记录,因此考虑到要用多线程并发执行,在写的过程中又遇到问题,我想统计所有子进程执行完毕总共的耗时,在第一个子进程创建前记录当前时间用System.currentTimeMillis()在后一个子进程结束后...
下面小编就为大家分享一篇Java父线程(或是主线程)等待所有子线程退出的实例,具有很好的参考价值,希望对大家有所帮助
适合:简单地获取纯文字网页的内容。需要创建子线程or修改爬取网页请在testpc.java中修改,webpc用于获取指定网页内容,runthread用于创建子线程爬虫,testpc则是主线程,用于管理子线程的创建、运行与等待。
主要介绍了Java创建子线程的两种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
程序是一段静态的代码,它是应用软件...线程是比进程更小的执行单位,一个进程在其执行过程中,可以产生多个线程,形成多条执行线索,每条线索,即每个线程也有它自身的产生、存在和消亡的过程,也是一个动态的概念。
Java多线程实现异步调用实例。运行Main可以看到结果。main是主线程,另有A,B,C三个线程用不同的时间跑完。
Java主线程等待所有子线程执行完毕在执行,其实在我们的工作中经常的用到,本篇文章就介绍了Java多线程--让主线程等待所有子线程执行完毕在执行,有需要的可以了解一下。