0

我无法与三个线程共享资源......

 public class Subject{

        int i;
        boolean valueSet1 = false;
        boolean valueSet2 = true;
        boolean valueSet3 = true;

    void put(int i){

        while(valueSet1){
            try{
                wait();
               }catch(InterruptedException e){
                    System.out.println("Producer thread interrupted");
                }
            }
            System.out.println("Producer thread wakesup");
            valueSet1=true;
            valueSet2=false;
            this.i=i;        
            System.out.println("Put: "+i);
            notify();
        }


    void makesquare(){

            int a;   
            while(valueSet2){
                try{
                    System.out.println("Convertor thread goin to sleep");
                    wait();
                }catch(InterruptedException e){
                    System.out.println("Convertor thread interrupted");
                }
            }       
            System.out.println("Convertor thread wakesup");
            valueSet2 = true;
            valueSet3=false;
            a = this.i;
            this.i = a*a;
            System.out.println("Made: "+i);        
            notify();
    }

    void get(){

           while(valueSet3){
                try{
                    System.out.println("Consumer thread goin to sleep");                
                    wait();
                }catch(InterruptedException e){
                    System.out.println("Consumer thread interrupted");
                }
            }
           System.out.println("Consumer thread wakesup");
           valueSet3 = true;
           valueSet1 = false;
           System.out.println("Got: "+i);
           notify();       
    }

    }

    class Producer implements Runnable{

        Subject q;    
        Thread t;
        String msg; 
        Producer(Subject q, String msg){
            this.q=q;
            this.msg = msg;
            t = new Thread(this, this.msg);
        }
        @Override
        public void run(){
            int i=2;
            while(true){
                synchronized(q){
                q.put(i++);
                }
            }
        }
    }
    class Consumer implements Runnable{

        Subject q;    
        Thread t;
        String msg;
        Consumer(Subject q,String msg){
            this.q = q;
            this.msg = msg;
            t = new Thread(this, this.msg);
        }
        @Override
        public void run(){
            while(true){
                synchronized(q){
                q.get();
                }
            }
        }
    }

    class Convertor implements Runnable{
        Subject q;   
        Thread t;
        String msg;
        Convertor(Subject q, String msg){
            this.q=q;
            this.msg = msg;
            t = new Thread(this, this.msg);    
        }
        @Override
        public void run(){
            while(true){
                synchronized(q){
                q.makesquare();
                }
            }
        }
    }

程序中有三个线程。一根线生产,而另一根线使生产量成平方。而最后一个线程消耗平方乘积。它们都共享同一个对象。

    public class Thread3way {

        public static void main(String[] args) {
           Subject q = new Subject();
           Producer P = new Producer(q, "producer");
           Convertor Cv = new Convertor(q, "convertor");
           Consumer Cs = new Consumer(q, "consumer");
           P.t.start();
           Cv.t.start();
           Cs.t.start();
        }
    }
4

2 回答 2

0

您的wait循环不太正确,您需要继续循环直到您的条件为真,然后再进行任何修改。我会这样做(使用State枚举使事情更清楚):

public class Subject {
    static enum State { EMPTY, WAITING_TO_SQUARE, WAITING_TO_GET };
    State state;
    int value;

    public synchronized void put(int i) {
        while (state != State.EMPTY) {
            try {
                wait();
            }catch(InterruptedException e) {
                System.out.println("Put interrupted");
            }
        }
        value = i;
        state = State.WAITING_TO_SQUARE;
    }
}

正如评论者指出的那样,您不需要同步两次,无论是synchronized(q)围绕Subject调用还是声明您的方法synchronized。你不需要两者。

无需Runnables显式使用,直接 make Producer, Convertor, Consumer Threads 即可。然后你就不需要这些t字段了,你可以像P.start().

于 2012-09-13T16:40:47.763 回答
0

在我看来,您正在做某种具有 3 个阶段的管道。为什么不享受以下好处ExecutorService

class ConvertorTask implements Runnable {

    private int number;
    private static ExecutorService consumer = Executors.newSingleThreadExecutor();

    public ConvertorTask(int number) {
        this.number = number;       
    }

    public void run() {
        consumer.submit(new ConsumerTask(number * number));
    }
}

class ConsumerTask implements Runnable {

    private int number;

    public ConsumerTask(int number) {
        this.number = number;       
    }

    public void run() {
        System.out.println(number);
    }
}

class Producer implements Runnable {

    private ExecutorService convertor = Executors.newSingleThreadExecutor();

    public void run() {
        int i = 0;
        while(true) {           
            convertor.submit(new ConvertorTask(i++));
        }
    }
}

public class Test {

    public static void main(String[] args) throws InterruptedException {        
        Thread t = new Thread(new Producer());
        t.start();
    }
}
于 2012-09-13T16:54:21.963 回答