为了账号安全,请及时绑定邮箱和手机立即绑定

java赋值同步生产者使用者

java赋值同步生产者使用者

慕森卡 2021-04-26 13:34:06
我已经针对生产者消费者问题编写了多线程代码,其中我在消费者和生产者线程的运行方法中编写了同步块,该块锁定了共享列表(我假设),所以问题的关键在于,是否会有锁定在列表上,因为每个线程都有自己的同步块,但是它们共享相同的列表实例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看起来像您想要的。


查看完整回答
反对 回复 2021-05-12
  • 2 回答
  • 0 关注
  • 103 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信