在生产者使用者示例中第二个线程未启动 [英] Second thread doesn't start in producer consumer example

查看:124
本文介绍了在生产者使用者示例中第二个线程未启动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试通过在Java中使用semaphores来实现生产者和消费者问题.问题是,当我启动两个线程(生产者和消费者)时,消费者不会启动,而生产者在缓冲区已满后会自行阻塞.我的意思是看起来只有一个线程以同步方式工作.因此,正如我提到的,我使用3个信号量,它们是空的,完整的和互斥的.这是最简单的代码;

I'm trying to implement Producer and Consumer problem by using semaphores in java. The issue is when I start two threads (Producer and Consumer) consumer doesn't start and producer blocks itself after buffer is full. I mean it looks like there is only one thread which works in synchronous manner. Thus, as I mentioned I use 3 semaphores which are empty, full, and mutex. Here is the simplest code;

生产者类别;

import java.util.concurrent.Semaphore;

public class Producer implements Runnable {

    private Semaphore empty;
    private Semaphore full;
    private Semaphore mutex;

    public Producer(Semaphore empty, Semaphore full, Semaphore mutex) {

        this.empty = empty;
        this.full = full;
        this.mutex = mutex;
    }

    @Override
    public void run() {

        while (true) {

            try {
                empty.acquire();
                mutex.acquire();
                Thread.sleep(500);
                System.out.println("Producer producess an element");
                mutex.release();
                full.release();
            } catch (InterruptedException e) {

                e.printStackTrace();
            }
        }
    }
}

消费类;

import java.util.concurrent.Semaphore;

public class Consumer implements Runnable {

    private Semaphore empty;
    private Semaphore full;
    private Semaphore mutex;

    public Consumer(Semaphore empty, Semaphore full, Semaphore mutex) {

        this.empty = empty;
        this.full = full;
        this.mutex = mutex;
    }

    @Override
    public void run() {

        while (true) {

            try {
                full.acquire();
                mutex.acquire();
                Thread.sleep(500);
                System.out.println("Consumer consumes an element");
                mutex.release();
                empty.release();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

ProducerConsumerExample类

ProducerConsumerExample class

import java.util.concurrent.Semaphore;

public class ProducerConsumerProblem {

    private Semaphore empty;
    private Semaphore full;
    private Semaphore mutex;

    public ProducerConsumerProblem(int empty, int full) {

        this.empty = new Semaphore(empty);
        this.full = new Semaphore(full);
        this.mutex = new Semaphore(1);

    }

    public void runProducerConsumerExample() {

        Producer producer = new Producer(empty, full, mutex);
        Consumer consumer = new Consumer(empty, full, mutex);

        Thread p = new Thread(producer);
        Thread c = new Thread(consumer);

        p.run();
        c.run();
    }
}

最后测试课

import org.junit.Before;
import org.junit.Test;

public class ProducerConsumerProblemTest {

    private ProducerConsumerProblem testClass;
    private static final int        EMPTY = 10;
    private static final int        FULL  = 0;

    @Before
    public void setUp() {

        testClass = new ProducerConsumerProblem(EMPTY, FULL);
    }

    @Test
    public void testName() {

        testClass.runProducerConsumerExample();
    }
}

输出:

Producer producess an element
Producer producess an element
Producer producess an element
Producer producess an element
Producer producess an element
Producer producess an element
Producer producess an element
Producer producess an element
Producer producess an element
Producer producess an element

产生10个项目后,什么也没有发生,并且线程被阻塞了.

After 10 items produced nothing happens and thread gets blocked.

推荐答案

不要使用run(),请使用start()

    p.run();
    c.run();

应该是

    p.start();
    c.start();

调用run()不会生成新的执行线程.它仅在当前执行线程中运行该功能.

Calling run() doesn't generate a new thread of execution. It merely runs the functionality within the current thread of execution.

请参见此问题/答案有关更多详细信息.

See this question/answer for more details.

还请注意,我会在测试运行结束时正确关闭线程(否则,您将在添加/运行测试时建立多个线程).中断您的线程或设置一个易失性布尔值,指示您的循环应完成.

Note also that I would shutdown the threads properly at the end of your test run (otherwise you'll build up multiple threads as you add/run tests). Interrupt your threads or set a volatile boolean indicating that your loops should complete.

这篇关于在生产者使用者示例中第二个线程未启动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆