Javaは待機をマルチスレッドと同じブロックに通知します

Mayank Vaid:

私は交互に2つのスレッドで順次番号を印刷する必要があるの小さな問題に取り組んでいます。スレッド1枚の印刷物1と同様に、2枚の版画2スレッド、1枚の版画3というようにスレッド...

私はそうはコードの部分の下に作成しているが、いくつかの点でのスレッドの両方がコンソールに待機状態と何も印刷さに入ります。

import java.util.concurrent.atomic.AtomicInteger;

public class MultiPrintSequence {

    public static void main(String[] args) {
        AtomicInteger integer=new AtomicInteger(0);
        Sequence sequence1=new Sequence(integer);
        Sequence sequence2=new Sequence(integer);
        sequence1.start();
        sequence2.start();
    }
}

class Sequence extends Thread{

    private AtomicInteger integer;
    boolean flag=false;

    public Sequence(AtomicInteger integer) {
        this.integer=integer;
    }

    @Override
    public void run() {
        while(true) {
            synchronized (integer) {
                while (flag) {
                    flag=false;
                    try {
                        System.out.println(Thread.currentThread().getName()+" waiting");
                        integer.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println(Thread.currentThread().getName()+" "+integer.incrementAndGet());
                flag = true;
                System.out.println(Thread.currentThread().getName()+" notifying");
                integer.notify();
            }
        }
    }
}

コンソール出力を観察すると、私は、スレッド通知の1いくつかの点で、他のスレッドが最終的に通知スレッドが待ち状態になっても前に開始したときに、したがって、ある時点でのスレッドの両方が待機状態に入ることに気づきました。以下のコンソール出力の小さい部分です。

Thread-1 510
Thread-1 notifying
Thread-1 waiting
Thread-0 511
Thread-0 notifying
Thread-0 waiting
Thread-1 512
Thread-1 notifying
Thread-1 waiting
**Thread-0 513
Thread-0 notifying
Thread-1 514
Thread-1 notifying
Thread-1 waiting
Thread-0 waiting**
兄 :

コードでは、整数は、アトミックとスレッド間で共有される場合でも、フラグ自体はそうではありません。

class Sequence extends Thread{

    private AtomicInteger integer; //shared
    boolean flag=false; //local

    public Sequence(AtomicInteger integer) {
      this.integer=integer;
    }

これは他の中で反映していない一つのスレッドに変化が生じます。

提案されたソリューション:

次の例のように、あまりにもフラグと共有のために原子力を利用して解決することができます。

import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;

public class StackOverflow {

    public static void main(String[] args) {
        AtomicInteger integer=new AtomicInteger(0);
        AtomicBoolean flag=new AtomicBoolean(true);
        Sequence sequence1=new Sequence(integer, flag);
        Sequence sequence2=new Sequence(integer, flag);
        sequence1.start();
        sequence2.start();
    }
}

そして、シーケンス:

import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;

class Sequence extends Thread{

    private final AtomicInteger integer;
    private AtomicBoolean flag;

    public Sequence(AtomicInteger integer, AtomicBoolean flag) {
        this.integer=integer;
        this.flag=flag;
    }

    @Override
    public void run() {
        while(true) {
            synchronized (integer) {
                while (flag.get()) {
                    flag.set(false);
                    try {
                        System.out.println(Thread.currentThread().getName()+" waiting");
                        integer.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println(Thread.currentThread().getName()+" "+integer.incrementAndGet());
                flag.set(true);
                System.out.println(Thread.currentThread().getName()+" notifying");
                integer.notify();
            }
        }
    }
}

これは、出力の一部です:

Thread-1 8566
Thread-1 notifying
Thread-1 waiting
Thread-0 8567
Thread-0 notifying
Thread-0 waiting
Thread-1 8568
Thread-1 notifying
Thread-1 waiting
Thread-0 8569
Thread-0 notifying
Thread-0 waiting

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=188825&siteId=1
おすすめ