Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/394.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 只有两个线程用于调用product和consume?_Java_Multithreading_Producer Consumer - Fatal编程技术网

Java 只有两个线程用于调用product和consume?

Java 只有两个线程用于调用product和consume?,java,multithreading,producer-consumer,Java,Multithreading,Producer Consumer,下面是关于运行生产者和消费者的线程的代码。 public class PC1 { public static final int limit = 3; public static void main(String[] args) { List bag = new ArrayList(); Producer p = new Producer(bag); Consumer c = new Consumer(bag);

下面是关于运行生产者和消费者的线程的代码。

public class PC1 {
    public static final int limit = 3;

    public static void main(String[] args) {
        List bag = new ArrayList();
        Producer p = new Producer(bag);
        Consumer c = new Consumer(bag);
        Thread t1 = new Thread(p, "t1");
        Thread t2 = new Thread(c, "t2");
        Thread t3 = new Thread(p, "t3");
        Thread t4 = new Thread(c, "t4");
        Thread t5 = new Thread(p, "t5");
        Thread t6 = new Thread(c, "t6");
        t2.start();
        t4.start();
        t6.start();
        t1.start();
        t3.start();
        t5.start();
    }
}

class Producer implements Runnable {
    private List bag;

    public Producer(List bag) {
        this.bag = bag;
    }

    @Override
    public void run() {
        synchronized (bag) {
            while (true) {
                while (bag.size() >= PC1.limit) {
                    bag.notify();
                    System.out.println(Thread.currentThread().getName() + "@@@@@@@@@@@");
                    try {
                        bag.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                int curr = bag.size();

                bag.add(++curr);
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + " produce " + curr);
            }
        }
    }

}

class Consumer implements Runnable {
    private List bag;

    public Consumer(List bag) {
        this.bag = bag;
    }

    @Override
    public void run() {
        synchronized (bag) {
            while (true) {
                while (bag.size() <= 0) {
                    bag.notify();
                    System.out.println(Thread.currentThread().getName() + "!!!!!!!!!!!");
                    try {
                        bag.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                int curr = bag.size();

                bag.remove(curr - 1);
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + " consume " + (bag.size() + 1));
            }
        }
    }

}   
公共类PC1{
公共静态最终整数限值=3;
公共静态void main(字符串[]args){
列表包=新的ArrayList();
生产者p=新生产者(袋);
消费者c=新消费者(袋);
螺纹t1=新螺纹(p,“t1”);
螺纹t2=新螺纹(c,“t2”);
螺纹t3=新螺纹(p,“t3”);
螺纹t4=新螺纹(c,“t4”);
螺纹t5=新螺纹(p,“t5”);
螺纹t6=新螺纹(c,“t6”);
t2.start();
t4.开始();
t6.开始();
t1.start();
t3.start();
t5.开始();
}
}
类生成器实现了Runnable{
私人名单袋;
公共制片人(名单袋){
这个袋子=袋子;
}
@凌驾
公开募捐{
同步(包){
while(true){
while(bag.size()>=PC1.limit){
bag.notify();
System.out.println(Thread.currentThread().getName()+“@@@@@@@@@”);
试一试{
等等;
}捕捉(中断异常e){
e、 printStackTrace();
}
}
int curr=袋大小();
加上(++货币);
试一试{
睡眠(100);
}捕捉(中断异常e){
e、 printStackTrace();
}
System.out.println(Thread.currentThread().getName()+“product”+curr);
}
}
}
}
类使用者实现Runnable{
私人名单袋;
公众消费者(列表袋){
这个袋子=袋子;
}
@凌驾
公开募捐{
同步(包){
while(true){

while(bag.size()Notify工作正常;即根据其指定方式。问题是Java不能保证对wait/Notify/notifyAll进行公平调度。这意味着某些线程可能比其他线程获得更多的工作

事实上,对于一个普通的程序来说,这并不重要:这根本不是问题。例如,在一个普通的多线程生产者/消费者应用程序中,哪个消费者线程处理生产者生产的东西并不重要。重要的是它们被高效地处理。实际上,这可能有性能优势在这种情况下,使用不公平的线程调度代替公平。一个原因是可以减少线程上下文切换的数量


那么你将如何实现你的目标呢

首先,不要使用wait/notify。如果您阅读这些方法的javadocs,您将看到没有公平性的保证


获得公平性的一种方法是使用
ReentrantLock
实例化为
fair==true
;有关详细信息,请参阅。

通知工作正常;即根据其指定方式。“问题”Java不能保证对wait/notify/notifyAll的公平调度,这意味着一些线程可能比其他线程得到更多的工作

事实上,对于一个普通的程序来说,这并不重要:这根本不是问题。例如,在一个普通的多线程生产者/消费者应用程序中,哪个消费者线程处理生产者生产的东西并不重要。重要的是它们被高效地处理。实际上,这可能有性能优势在这种情况下,使用不公平的线程调度代替公平。一个原因是可以减少线程上下文切换的数量


那么你将如何实现你的目标呢

首先,不要使用wait/notify。如果您阅读这些方法的javadocs,您将看到没有公平性的保证


获得公平性的一种方法是使用实例化为
fair==true
ReentrantLock
;有关详细信息,请参阅。

如果您将拥有多个生产者和一个消费者,则必须使用
notifyAll()
;或者必须放弃wait()/notify()总之,切换到一个
可重入锁定
,并使用两个
条件

使用
notify()的问题
当存在多个生产者或消费者时,在某些情况下,生产者可以唤醒另一生产者,消费者也可以唤醒另一消费者。一旦发生这种情况,循环就会中断,程序将无法再取得任何进展。有点像死锁:每个线程都在等待某个ot她想做点什么


该问题的奇特解决方案是使用单独的
条件
变量:一个用于生产者唤醒消费者,另一个用于消费者唤醒生产者。解决该问题的钝器方法是使用
notifyAll()
然后把所有人都叫醒。

如果你要有不止一个生产者和一个消费者,那么你必须使用
notifyAll()
;或者你必须完全放弃wait()/notify(),改为切换到
ReentrantLock
,并使用两个
条件

使用
notify()的问题
当存在多个生产者或消费者时,在某些情况下,生产者可以唤醒另一生产者,消费者也可以唤醒另一消费者。一旦发生这种情况,循环就会中断,程序将无法再取得任何进展。有点像死锁:每个线程都在等待某个ot她想做点什么

这个问题的奇特解决方案是有单独的
条件
变量:一个用于生产者唤醒消费者,另一个用于消费者唤醒生产者。解决这个问题的钝器方法是使用
notifyAll()
,然后唤醒所有人。

Stephen的答案