java赋值同步生产者使用者

我已经针对生产者消费者问题编写了多线程代码,其中我在消费者和生产者线程的运行方法中编写了同步块,该块锁定了共享列表(我假设),所以问题的关键在于,是否会有锁定在列表上,因为每个线程都有自己的同步块,但是它们共享相同的列表实例


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

                }

    

慕森卡
浏览 104回答 2
2回答

慕标5832272

是的,互斥体/监视器与JavaObject实例相关联,该实例是该实例中的共享列表。这意味着所有线程都锁定相同的互斥锁(与关联queue,并通过此同步)。因此,好的一面是:您的程序实际上是线程安全的。但是,实际上,从多种方式来看,额外的信号量并没有多大意义:这些检查(例如,对availablePermits的检查)发生在锁之外,因此仅是关于队列状态的最佳猜测。此后不久可能会有所不同。试图在一个锁中获取一个信号量,该信号量只能在同一锁中释放,这看起来像是一个确保死锁的方法。正如AnDus所提到的,可以通过使用充当条件变量的wait和notify方法来更好地解决此问题。您很可能甚至需要两个,一个用于解除生产者的封锁,另一个用于解除消费者的封锁。通常,如果这不是编码工作,请使用已经实现所需功能的类。在这种情况下,java.util.concurrent.BlockingQueue看起来像您想要的。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java