0

在下面的代码中,我希望 Thread t1 执行 Runnable 的产生,而 Thread t2 执行 Runnable 的消耗。这行得通吗?

class Processor implements Runnable {
    @override
    run(){
        produce();
        consume();
    }
    void produce(){
        // code to produce, synchronize
    }
    void consume(){
        // code to consume, synchronize
    }
}

Class App {
    public static void main(String[] args){
        Processor p = new Processor()
        Thread t1 = new Thread(p);
        t1.start();
        Thread t2 = new Thread(p); 
        t2.start();
    }
}
4

4 回答 4

3

在下面的代码中,我希望 Thread t1 执行 Runnable 的产生,而 Thread t2 执行 Runnable 的消耗。

第一个答案是您很可能不想这样做。你应该有一个生产者类和一个消费者类。如果他们需要共享数据,那很好,但是出于模块化目的,您应该将生产者和消费者代码分开。例如,生产者和消费者代码可以共享一个BlockingQueue将传递给两个类并用于它们交换工作的代码。

由于您当前编写的代码,每个线程显然只是要调用produce()then consume()。我假设代码是作为示例编写的。

如果你真的想将生产者和消费者代码组合在同一个类中,你可以传递某种布尔值或其他选择器来告诉线程要么生产要么消费。

例如:

 public class ProducerConsumerRunnable implements Runnable {
      private final Processor processor;
      private final boolean consume;
      public ProducerConsumerRunnable(Processor processor, boolean consume) {
          this.processor = processor;
          this.consume = consume;
      }
      public void run() {
          if (consume) {
              processor.consume()
          } else {
              processor.produce()
          }
      }
 }

那么你会像这样开始你的线程:

Processor p = new Processor()
Thread producerThread = new Thread(new ProducerConsumerRunnable(p, false));
producerThread.start();
Thread consumerThread = new Thread(new ProducerConsumerRunnable(p, true));
consumerThread.start();

编辑:

thread.run()当您应该调用thread.start(). 调用run()只会在前台线程中运行 runnable,而start()实际上会在后台分叉一个线程,然后调用 run。

于 2013-06-24T20:37:01.240 回答
0

这样做的正确方法:

class App {
    public static void main(String[] args){
        Thread t1 = new Thread(){
            @Override run(){
                //insert produce method here
            }
        }
        Thread t2 = new Thread(){
            @Override run(){
                //insert consume method here
            }
        }
        t1.start(); // NOT run()!
        t2.start();
    }
}

这样,您可以将两个线程之间需要的任何共享变量添加到App类中。

另外,正如我在代码中指出的那样,您使用Thread.start()的是启动一个新线程,而不是Thread.run().

于 2013-06-24T20:38:01.453 回答
0

No. Both threads would call produce and consume.

You should create 2 different runnables. One for the produce routine, and one for the consume routine.

Have one thread execute the produce runnable, and one thread execute the consume runnable.

于 2013-06-24T20:35:34.837 回答
0

如前所述,两个线程都会进行两个函数调用。在大多数情况下,您最好将produce() 和consume() 函数放在不同的类中;如果有很多其他共享逻辑,请使用继承使它们都成为某个公共基类的子类(如果需要,可能是抽象的),这实现了共享逻辑。

如果他们绝对肯定是同一个类(他们可能不是),你可以尝试在处理器类中添加一个布尔值,比如

class Processor implements Runnable
{
public Boolean producer;
@override
run()
{
if(producer){
    produce();
}
else{
    consume();
}
}
void produce()
{
// code to produce, synchronize
}
void consume()
{
// code to consume, synchronize
}
}

并在运行它们之前将一个设置producer为 false,另一个设置为 true。

于 2013-06-24T20:39:29.783 回答