Java---12--マルチスレッド練習:チケット販売---データ共有を実現


1つの練習をします:切符の小さいプログラムを売って、データの共有を実現します.
 
まずスレッドを作成し、メインスレッドと交互に実行します.
 
これは簡単です.
Threadクラスを継承する方法で言いましょう.
class MyThread extends Thread
{
    private int num = 150;
    private String name;
    public MyThread(String name)
    {
        super(name);
    }
    public void run ()
    {
        while (num >= 0)
        {
            System.out.println(Thread.currentThread().getName()+"..."+num--);
        }
    }
}
public class THREAD
{
    public static void main (String[] args)
    {
        MyThread a = new MyThread("My");
        MyThread b = new MyThread("Your");

        a.start();
        b.start();
    }
}

この例ではnumの値が繰り返し印刷されていることがわかります.これは私たちの実際の生活の現象と一致しません.例えば、切符を売っています.
駅で切符を売るときは複数の窓口で同時に行われていましたが、重複した切符は見つかりませんでした.
チケットを販売する4つのウィンドウに相当する4つのスレッドを作成します.
class MyThread extends Thread
{
    private int num = 150;
    private String name;
    public MyThread(String name)
    {
        super(name);
    }
    public void run ()
    {
        while (num >= 0)
        {
            System.out.println(Thread.currentThread().getName()+"..."+num--);
        }
    }
}
public class THREAD
{
    public static void main (String[] args)
    {
        MyThread a = new MyThread("one");
        MyThread b = new MyThread("two");
        MyThread c = new MyThread("three");
        MyThread d = new MyThread("four");

        a.start();
        b.start();
        c.start();
        d.start();
    }
}

しかし、運行結果によると、1枚あたり4回も繰り返し販売されているが、現実にこのような状況が発生すれば、家に帰っても切符が買えないのだろうか.
どのように解決しますか.
 
num変数をstaticとして宣言します.
データをstatic静的に定義し、データ共有を実現する:
class MyThread extends Thread
{
    private static int num = 150;
    private String name;


    public MyThread(String name)
    {
        super(name);
    }


    public void run ()
    {
        while (num >= 0)
        {
            System.out.println(Thread.currentThread().getName()+"..."+num--);
        }
    }
}
public class THREAD
{
    public static void main (String[] args)
    {
        MyThread a = new MyThread("one");
        MyThread b = new MyThread("two");
        MyThread c = new MyThread("three");
        MyThread d = new MyThread("four");

        a.start();
        b.start();
        c.start();
        d.start();
    }
}

Threadクラスを継承する方法ではデータ共有が実現されていますが、静的ライフサイクルが長すぎるため、一般的には静的を定義しません.
ではRunnableインタフェースを実装する方法はどうすれば実現できるのでしょうか.
まず,この方法で4つのスレッドを作成してスレッドの実行を実現する.
class MyThread implements Runnable
{
    private static int num = 150;
    public void run ()
    {
        while (num >= 0)
        {
            System.out.println(Thread.currentThread().getName()+"..."+num--);
        }
    }

}

public class THREAD
{
    public static void main (String[] args)
    {
        MyThread a = new MyThread();
        Thread a1 = new Thread(a);
        Thread a2 = new Thread(a);
        Thread a3 = new Thread(a);
        Thread a4 = new Thread(a);

        a1.start();
        a2.start();
        a3.start();
        a4.start();

    }
}

実行すると、切符を売るプログラムが実現し、データ共有が実現されていることがわかりました.これはどういうことですか.
なぜRunnableインタフェースを実現する方法でよいのでしょうか.
では、まずこの問題を考えてみましょう.
なぜRunnableインタフェースのサブクラスオブジェクトを実際のパラメータとしてThreadクラスのコンストラクタに渡すのですか?
カスタムrunメソッドが属するオブジェクトはRunnableインタフェースのサブクラスオブジェクトであるため、
スレッドが起動するとrunメソッドも実行されますが、新しいnewのThreadオブジェクトにはrunメソッドが複写されません.
スレッドを実行するにはrunメソッドが必要ですが、自分ではありませんので、runメソッドが属するオブジェクトを明確にします.借りたRunnableサブクラスオブジェクトに相当するrunメソッドです.
これで、チケット販売プログラムの2つの方法が実現された.
クリックしてリンクを開く