我已经针对生产者消费者问题编写了多线程代码,其中我在消费者和生产者线程的运行方法中编写了同步块,该块锁定了共享列表(我假设),所以问题的关键在于,是否会有锁定在列表上,因为每个线程都有自己的同步块,但是它们共享相同的列表实例public class Main { static boolean finishFlag=false; final int queueSize = 20; List<Integer> queue = new LinkedList<>(); Semaphore semaphoreForList = new Semaphore(queueSize); public Main(int producerCount,int consumerCount) { while(producerCount!=0) { new MyProducer(queue,semaphoreForList,queueSize).start(); //produces the producer producerCount--; } while(consumerCount!=0) { new MyConsumer(queue,semaphoreForList,queueSize).start(); //produces the consumer consumerCount--; } } public static void main(String args[]) { /* * input is from command line 1st i/p is number of producer and 2nd i/p is number of consumer */ try { Main newMain = new Main(Integer.parseInt(args[0]),Integer.parseInt(args[1])); try { Thread.sleep(30000); } catch(InterruptedException e) { } System.out.println("exit"); finishFlag=true; } catch(NumberFormatException e) { System.out.println(e.getMessage()); } }}class MyProducer extends Thread{ private List<Integer> queue; Semaphore semaphoreForList; int queueSize; public MyProducer(List<Integer> queue, Semaphore semaphoreForList,int queueSize) { this.queue = queue; this.semaphoreForList = semaphoreForList; this.queueSize = queueSize; } public void run() { while(!Main.finishFlag) { try { Thread.sleep((int)(Math.random()*1000)); } catch(InterruptedException e) { } try { if(semaphoreForList.availablePermits()==0) {//check if any space is left on queue to put the int System.out.println("no more spaces left"); }
2 回答
慕标5832272
TA贡献1966条经验 获得超4个赞
是的,互斥体/监视器与JavaObject
实例相关联,该实例是该实例中的共享列表。这意味着所有线程都锁定相同的互斥锁(与关联queue
,并通过此同步)。
因此,好的一面是:您的程序实际上是线程安全的。
但是,实际上,从多种方式来看,额外的信号量并没有多大意义:
这些检查(例如,对availablePermits的检查)发生在锁之外,因此仅是关于队列状态的最佳猜测。此后不久可能会有所不同。
试图在一个锁中获取一个信号量,该信号量只能在同一锁中释放,这看起来像是一个确保死锁的方法。
正如AnDus所提到的,可以通过使用充当条件变量的wait和notify方法来更好地解决此问题。您很可能甚至需要两个,一个用于解除生产者的封锁,另一个用于解除消费者的封锁。
通常,如果这不是编码工作,请使用已经实现所需功能的类。在这种情况下,java.util.concurrent.BlockingQueue
看起来像您想要的。
添加回答
举报
0/150
提交
取消