0 0

关于多线程通讯地一个疑问20

新手学JAVA,学到多线程,编了一个简单地电脑城进出货模拟系统。
代码有点长,主要部分如下所述:
有三方:厂家,电脑城,顾客
厂家2个,一个生产主板,一个生产显卡。
顾客有2个,他们各自不断购买主板和显卡。
电脑城有一个,卖显卡和主板。

限于篇幅问题,摘录主要代码如下:
--------------------------厂家类---------------------------------------
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 显卡;
	}

}

-------------------------------------顾客类-------------------------------------------
public class customer implements Runnable
{
	public void run()
	{
		while(true)
		{
			buyVC("ATI");
			//顾客不断购买显卡和主板
			buyMB("MSI");
		}
	}

}

-----------------------------电脑城类-----------------------------------------
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 写道
主要问题是 显卡 没了,等显卡送来,主板没了等主板送来。
不能人家来买显卡的,你进来一个主板也通知人家来买。
写了个例子,你看看。
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 写道
噢,对不起,我是没有考虑这个情况。
你说的那种方法应该能够实现,我等待后再判断的方法试了试,要使,你看看
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 写道


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年7月25日 18:33

6个答案 按时间排序 按投票排序

0 0

采纳的答案

没怎么写过多线程,拿来练练手,未必正确。

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;
    }
}

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;
    }
}

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." );
        }
    }
}

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;
            }
        }
    }
}

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();
    }
}


2010年7月26日 21:31
0 0

lz基本的问题就是,厂商和客户等的不是同一把锁,所以要分别对待。然后就简单了。不过我的StockManager看着也不怎么对劲儿。

2010年7月26日 21:36
0 0

恩,是有点儿,这样你看行不行,也就是顾客在买的时候,如果没有等待,买完后也不通知。电脑城在进货满之后不等待(或者sleep也行,让出cpu,现实中像是卖一段时间在进货),没进一个货就通知一声,只通知一个顾客。

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();
		}
	}  
}

2010年7月26日 19:19
0 0

噢,对不起,我是没有考虑这个情况。
你说的那种方法应该能够实现,我等待后再判断的方法试了试,要使,你看看

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();
		}
	}  
}

2010年7月26日 17:17
0 0

主要问题是 显卡 没了,等显卡送来,主板没了等主板送来。
不能人家来买显卡的,你进来一个主板也通知人家来买。
写了个例子,你看看。

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) {} 可以模拟不同的情况。

2010年7月26日 11:19
0 0

1.消费者由生产唤醒,每次唤醒队列中的一个,A买完就走,不要多管闲事
2.不同的产品在不同的队列中,不要排别人的队
3.4.同2

2010年7月26日 09:08

相关推荐

    linux下的socket多线程通讯

    在linux下用socket的多线程通讯实现一个服务器和多个客户端之间的相互通讯。如果要实现多个和多个客户端通讯,则只需将里面的thread_client编译成多个文件即可。代码绝对是能用的~有什么疑问请留言~希望对大家伙有...

    AS/400-多线程编程技术.pdf

    多线程编程的一个重要特性是在同一JOB内可以创建多个线程,这些线程共享JOB的资源,但每个线程也有其独立的执行环境。 ###### 1.3.4 线程的私有数据和共有数据 - **私有数据**:每个线程独有的数据,不会被其他...

    汪文君高并发编程实战视频资源下载.txt

     高并发编程第三阶段30讲 使用Condition实现一个多线程下的Producer-Consumer_.mp4  高并发编程第三阶段31讲 JDK8-StampedLock详细介绍-上_.mp4  高并发编程第三阶段32讲 JDK8-StampedLock详细介绍-下.mp4  高...

    汪文君高并发编程实战视频资源全集

     高并发编程第三阶段30讲 使用Condition实现一个多线程下的Producer-Consumer_.mp4  高并发编程第三阶段31讲 JDK8-StampedLock详细介绍-上_.mp4  高并发编程第三阶段32讲 JDK8-StampedLock详细介绍-下.mp4  高...

    即時通訊實例

    2. **多线程**:即时通讯系统需要处理并发连接,因此多线程编程是必不可少的。C#的System.Threading命名空间提供了Thread、Mutex、Semaphore等类,用于管理并发操作和同步。 3. **消息队列**:为了处理大量并发请求...

    基于Java的msn聊天程序Java仿真代码.zip

    【描述】中的内容与标题一致,确认了这是一个关于Java编程的项目,主要关注点在于创建一个聊天应用程序,模拟MSN的功能。 【标签】“Java”揭示了该项目的核心技术,Java是一种广泛使用的面向对象的编程语言,以其...

    java聊天程序源代码.pdf

    这个Java聊天程序源代码展示了一个基本的客户端-服务器架构的即时通讯应用。以下是该程序涉及的关键知识点: 1. **Socket编程**: - `Socket` 类在Java中用于网络通信,它代表了客户端和服务器之间的连接。在这个...

    小小聊天程序代码——首次运行客户端可以向服务端发信息,不知道为什么之后相互就不能发信息了

    这是一个关于使用Java编程语言开发简单聊天程序的问题。在这个程序中,包含了两个主要的文件:`XueLiangServer.java` 和 `XueLiangClient.java`,分别代表服务器端和客户端。初学者在尝试实现一个基本的即时通讯功能...

    SMS短信API

    API使用的网关服务器拥有多线程发送能力,每秒可同时处理数十个客户端的并发请求。   平台无关性 客户端适用于任何可运行JAVA的平台,包括:Windows、LINUX、UNIX、MAC等。 不像DLL接口,只能运行于WINDOWS平台...

    课4金牌电商客服.pptx

    4. **时间管理**:高效率地处理多线程工作,确保快速响应客户需求。 5. **数据分析**:理解数据背后的趋势,为优化服务和提升业绩提供依据。 此外,持续的培训和发展也是培养金牌客服的关键。企业应定期进行客服...

    Visual_Studio.NET相关词汇中英翻译

    活动文档包容是指一种技术,它允许一个文档对象作为活动对象被嵌入到另一个应用程序中。这种技术使得文档能够在不同的应用程序之间共享和交互。 #### 活动结尾 (Active End) 活动结尾通常指的是一个操作或流程的...

    iphone实用项目-淘宝客户端

    5. 异步处理:运用Grand Central Dispatch(GCD)进行多线程处理,提升用户体验。 四、性能优化 1. 离线缓存:对常用数据进行本地缓存,即使在网络不稳定时也能正常使用。 2. 懒加载:对于非首屏内容,采用懒加载...

    Android项目源码仿微信登录注册聊天换肤二维码扫描.zip

    实现一个IM实时聊天应用,少不了弄服务器,目前开源的Openfire服务器就比较合适,而且很多功能都已经封装好了,实现聊天APP就简洁很多。服务器后端的数据库我选择了MySQL,当然Openfire也支持大部分的主流数据库,...

    飞鸽传书(IPMessenger) 源码

     有了上边的知识,开发文件传输功能就变得简单多了,文件的接受也可以类推了,同样开启一个线程维护接受文件链表,逐次接受身下的文件,链表为空时。文件传输会遇到文件读写问题,有的文件发送是被打开了,这样会...

    Java-Push-Framework:Push Framework 的 Java 版本(旨在简化高性能服务器开发的 C++ 库)

    Java-Push-Framework 是一个基于Java的开源框架,它的设计目标是为开发者提供一个高效、易用的工具,用于构建高性能的服务器应用。这个框架是Push Framework的Java实现,原版Push Framework是一个C++库,专门针对...

Global site tag (gtag.js) - Google Analytics