2つのスレッドが交互に実行、スレッド1が10回実行、スレッド2が5回実行、交互に15回

**

2つのスレッドが交互に実行されます

**
最近、インタビューの質問を見ました。2つのスレッドが交互に10回実行され、スレッド1は10回、スレッド2は5回、交互に15回繰り返されました。

方法1

1つのメインスレッドと1つのサブスレッド。サブスレッドはメインスレッド内で実行され、交互に出力をそれぞれ10回と5回、交互に15回実行します。

package com.example.xssDemo.xss.util;

/**
 * @author liaoc
 */
public class ThreadPractice {
    public static void main(String[] args) {
        Do ado = new Do();
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 1; i <= 15; i++) {
                    ado.sub(i);
                }
            }
        }).start();

        for (int j = 1; j <= 15; j++) {
            ado.main(j);
            System.out.println("===========第" + j + "轮完成===================");
        }
        System.out.println("===================================");
    }

    static class Do {
        private boolean isSun = true;
        //isSun为true执行该方法
        public synchronized void sub(int i) {
            if (!isSun) {
                try {
                    //wait()使当前线程阻塞,前提是 必须先获得锁,一般配合synchronized 关键字使用
                    //当线程执行wait()方法时候,会释放当前的锁,然后让出CPU,进入等待状态
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            for (int j = 1; j <= 10; j++) {
                System.out.println("子线程:" + Thread.currentThread().getName() + "," +
                        i + "趟," + "第:" + j + "个");

            }
            isSun = false;
            /**
             * notify方法只唤醒一个等待(对象的)线程并使该线程开始执行。
             * 所以如果有多个线程等待一个对象,这个方法只会唤醒其中一个线程,
             * 选择哪个线程取决于操作系统对多线程管理的实现。
             * notifyAll 会唤醒所有等待(对象的)线程,尽管哪一个线程将会第一个处理取决于操作系统的实现。
             * 如果当前情况下有多个线程需要被唤醒,推荐使用notifyAll 方法
             */
            this.notify();
        }
        //isSun为false执行该方法
        public synchronized void main(int i) {
            if (isSun) {
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            for (int j = 1; j <= 5; j++) {
                System.out.println("主线程:" + Thread.currentThread().getName() + "," + i
                        + "趟," + j + "个");
            }
            isSun = true;
            this.notify();
        }
    }
}
方法2

2つの並列サブスレッドは交互に実行され、それぞれ10回と5回、交互に15回出力されます。

package com.example.xssDemo.xss.util;

/**
 * @author liaoc
 */
public class BrotherThread {
    public static void main(String[] args) {
        Dto dto = new Dto();
        /**
         * 两个并列线程交替执行,输出10次,供交替20次
         */
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 1; i <= 15; i++) {
                    dto.sub1(i);
                    System.out.println("我是:" + Thread.currentThread().getName() + "第" + i + "趟");
                }
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int j = 1; j <= 15; j++) {
                    dto.sub2(j);
                    System.out.println("我是:" + Thread.currentThread().getName() + "第" + j + "趟");
                }
            }
        }).start();
    }

    static class Dto {
        private boolean isSun = true;

        //isSun为true执行
        public synchronized void sub1(int i) {
            if (!isSun) {
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            for (int j = 1; j < 10; j++) {
                System.out.println(Thread.currentThread().getName() + "的第:" + i + "趟的第" + j + "个");
            }
            isSun = false;
            this.notify();
        }

        //isSun为false执行
        public synchronized void sub2(int i) {
            if (isSun) {
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            for (int j = 1; j <= 5; j++) {
                System.out.println(Thread.currentThread().getName() + "的第:" + i + "趟的第" + j + "个");
            }
            isSun = true;
            this.notify();
        }
    }
}

ところで、スレッドの一般的なキーワードを確認してください:
1.start()とrun()

start()メソッドはスレッドを開始するためのメソッドであり、このメソッドの実行後、スレッドは実際にRUNNABLE状態になります。run()メソッドは、スレッドで実行される特定のビジネスアクティビティです。通常、run()メソッドは書き換える必要があります
。2. stop()メソッドは、スレッドを直接終了し、スレッドが保持しているロックをすぐに解放します
。 interrupt()メソッドは、ターゲットスレッドに割り込みを通知する、つまり、割り込みフラグビットを設定するインスタンスメソッドです。4。sleep
()メソッドは、現在のスレッドをしばらくスリープさせるためのものであり、InterruptedException割り込み例外をスローします。任意のオブジェクトのロックリソースを解放する5.
wait()waitメソッドはObjectクラスのメソッドであり、オブジェクトインスタンスでwait()メソッドが呼び出されると、現在のスレッドはこのオブジェクトで待機します。では、待機はいつ終了しますか?スレッドは、他のスレッドがこのオブジェクトのnotify()メソッドを呼び出すまで待機します。このようにして、インスタンスオブジェクトは複数のスレッド間の通信手段になります。wait()とnotify()は簡単に呼び出すことはできません。対応するsynchronizeステートメントに含める必要があります。どちらのメソッドも最初にターゲットオブジェクトのリスナーを取得する必要があり、wait()メソッドとnotify()メソッドは実行後に解放されます。このリスナー。wait()メソッドは、ターゲットオブジェクトのロックを解放します。
6. join()メソッドは無制限の待機を意味し、ターゲットスレッドが実行されるまで現在のスレッドをブロックします。join(長いミリ秒)は最大待機時間を提供します。ターゲットスレッドが指定された時間を超えてまだ実行されている場合、現在のスレッドは待機せず、実行を継続します。

7. yeild()メソッドは静的メソッドであり、実行されると、現在のスレッドがCPUを放棄します。CPUをあきらめることは、現在のスレッドが実行されなくなったことを意味するのではなく、CPUリソースを奪い合うことにもなります。スレッドが重要でない場合、または優先度が比較的低い場合は、このメソッドを呼び出して、重要なスレッドに実行するリソースを与えることができます。
8. volatile:
並行プログラミングの3つの重要な機能:原子性、可視性、および順序

原子性:1つ以上の操作で、すべての操作が実行され、何らかの要因によって中断されないか、またはすべての操作が実行されないことを意味します。
可視性:スレッドが共有変数を変更すると、他のスレッドはすぐに最新の値を確認できます。
順序付け:いわゆる順序付けとは、実行中のプログラムコードの順序を指します。Javaコンパイルとランタイムの最適化により、コードの実行順序は、必ずしも開発者がコードを記述した順序とは限りません

67件の元の記事を公開 いいね12 10,000人以上の訪問者

おすすめ

転載: blog.csdn.net/m0_37635053/article/details/104698022