0

1 つの印刷 { 1,3,5,7,9} と別の印刷 {2,4,6,8,10} の 2 つのスレッドがあります。

{1,2,3,4,5,6,7...} を印刷したい

package com.oddnumber.threading;

public class NumberPrint implements Runnable {
  int number=1;
  private Object lock = new Object();
  private volatile boolean isOdd = false;

  public void generateEvenNumbers(int number) throws InterruptedException {
    synchronized (lock) {
      while (isOdd == false) {
        lock.wait();
      }
      System.out.println("even" + number);
      isOdd = false;
      lock.notifyAll();
    }
  }

  public void generateOddNumbers(int number) throws InterruptedException {
    synchronized (lock) {
      while (isOdd == true) {
        lock.wait();
      }
      System.out.println("odd" + number);
      isOdd = true;
      lock.notifyAll();
    }
  }

  @Override
  public void run() {
    while(true) {
      if(number%2 == 0) {
        try {
          generateEvenNumbers(number);
          number++;
          Thread.sleep(1112);
        } catch (InterruptedException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
        }
      } else {
        try {
          generateOddNumbers(number);
          number++;
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }
    }
  }     
}

私はそれを使用して実行しました:

package com.oddnumber.threading;
public class Test
{
  public static void main(String[] args) {
    NumberPrint n1 = new NumberPrint();
    NumberPrint n2 = new NumberPrint();
    new Thread(n1).start();
    new Thread(n2).start();
  }
}

出力:

 1
 1
 2
 2
 3
 3
 4
 4
 5
 5
 6
 6
 7
 8
 7
 8
 9
 9
 10

各数値は 2 回出力されますが、数値変数が 2 つのスレッド間で共有されないのはなぜですか?

4

4 に答える 4

0

最初に、2 つのスレッド間で変数が共有されるようにNumberPrint static(おそらく)に変数を作成する必要があります。static volatileこれはnumberlock、およびに対して行う必要がありisOddます。ただし、それだけの場合、出力は {1, 2, 1, 4, 5, 6, 7, 8, ...} になりますnumber。任意の同期。最善の解決策は、同期後に共有を確認generateEvenNumbersして読み取ることです。これは、これらのルーチンへのパラメーターを取り除くことを意味し、読み取ったときに共有されます。generateOddNumbersnumbernumbernumber

于 2013-08-27T16:26:26.590 に答える
0

NormR が言ったように、2 つのスレッドは同じロックを共有する必要があります。

public class Main {

    public static void main(String[] args) throws InterruptedException {
        Object lock = new Object();

        Thread evenThread = new Thread(new GeneratorHandler(lock, new EvenGenerator()));
        Thread oddThread = new Thread(new GeneratorHandler(lock, new OddGenerator()));

        oddThread.start();
        Thread.sleep(500);
        evenThread.start();

    }

}

public interface Generator {
    public int generate();
}

public class EvenGenerator implements Generator {
    int n = 0;

    @Override
    public int generate() {
        return n += 2;
    }
}

public class OddGenerator implements Generator {
    int n = -1;

    @Override
    public int generate() {
        return n += 2;
    }
}

public class GeneratorHandler implements Runnable {

    private Object lock;
    private Generator generator;

    public GeneratorHandler(Object lock, Generator generator) {
        this.lock = lock;
        this.generator = generator;
    }

    @Override
    public void run() {
        while (true) {

            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            synchronized(lock){
                System.out.println(generator.generate());
            }


        }
    }

}
于 2013-08-27T17:11:07.973 に答える