模擬列車発券システムはスレッド同期技術で実装され、500枚のチケットが6つのウィンドウで販売されます。各チケットウィンドウのチケット番号と発券時刻はオフィスで印刷されます。

実装のアイデア:マルチスレッドでは、6つのスレッドが直接作成され、投票数が個別に変更される場合、そのような同時操作はスレッドセーフではありません。ここでの安全性が低い理由は、複数のスレッドが同じ変数を同時に変更するためです。 。ここでの投票数は、複数のスレッドで共有できるデータです。スレッド1が読み取ると、他のスレッドもそれを読み取ります。スレッド1がメモリを変更してからメモリに書き戻すと、他のスレッドが取得した投票数が不正確になります。 。


理解しにくいかもしれません。たとえば、ウィンドウ1がまだチケットがあることを検出すると、チケットを販売し、データベースの投票数を更新する時間がありません。ウィンドウ2に表示される投票数は次のとおりです。まだ1.他の人が買ったのですが、チケットが2回売られたという状況がありました。この状況は、実際に発生した場合は非常に悪く、マルチスレッドにはそのような隠れた危険性があります。最終的に、その理由は、複数のスレッドが同じ変数を同時に変更するためです。

解決策->投票数を変更する方法にロックを追加します。ここでのロックは同期され、同期されると相互排除効果があります。スレッドがオブジェクトの同期に対して実行される場合、他のスレッドも同じに対して実行される場合同期されたオブジェクトは待機をブロックします。

人がトイレに行くとき、ドアを閉め、他の人を入れないことが理解できます。彼が出て行った場合にのみ、他の人が入ることができます。ここで同期されるのは、投票数の変更がスレッドセーフであることを確認するためです。

実装コード:
現在のシステム時刻の取得、スレッドスリープ、匿名内部クラス作成スレッド、try、catchによる例外のキャッチなど、理解できると思うので、コメントされていない小さな詳細がまだいくつかあります。

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * Created with IntelliJ IDEA.
 *
 * @Author: 管坤坤
 * @Date: 2021/12/08/19:59
 * @Description:
 */
class  Count{
    
    
    Date date=new Date ();
    SimpleDateFormat dateFormat=new SimpleDateFormat ("yyyy-MM-dd :hh:mm:ss");
  static   int count=600;
    synchronized     public   void ticket(){
    
    
        if(count>0){
    
    
            System.out.println(Thread.currentThread().getName()+"票号"+count+"  出票时间:  "+dateFormat.format (date));
            count--;
        }
    }
}
public class threadDemo13 {
    
    
    public static void main (String[] args) throws InterruptedException {
    
    
        Count count=new Count ();
        Thread t1=new Thread ("窗口1"){
    
    
            @Override
                public  void  run(){
    
    
                while (true){
    
    
                    count.ticket ();
                    try {
    
    
                        Thread.sleep (100);
                    } catch (InterruptedException e) {
    
    
                        e.printStackTrace ();
                    }
                }
            }
        };
        Thread t2=new Thread ("窗口2"){
    
    
            @Override
                 public  void  run(){
    
    
                while (true){
    
    
                    count.ticket ();
                    try {
    
    
                        Thread.sleep (100);
                    } catch (InterruptedException e) {
    
    
                        e.printStackTrace ();
                    }
                }
            }
        };
        Thread t3=new Thread ("窗口3"){
    
    
            @Override
                public  void  run(){
    
    
                while (true){
    
    
                    count.ticket ();
                    try {
    
    
                        Thread.sleep (100);
                    } catch (InterruptedException e) {
    
    
                        e.printStackTrace ();
                    }
                }
            }
        };
        Thread t4=new Thread ("窗口4"){
    
    
            @Override
            public  void  run(){
    
    
                while (true){
    
    
                    count.ticket ();
                    try {
    
    
                        Thread.sleep (100);
                    } catch (InterruptedException e) {
    
    
                        e.printStackTrace ();
                    }
                }
            }
        };
        Thread t5=new Thread ("窗口5"){
    
    
            @Override
             public  void  run(){
    
    
                while (true){
    
    
                    count.ticket ();
                    try {
    
    
                        Thread.sleep (100);
                    } catch (InterruptedException e) {
    
    
                        e.printStackTrace ();
                    }
                }
            }
        };
        Thread t6=new Thread ("窗口6"){
    
    
            @Override
           public  void  run(){
    
    
                while (true){
    
    
                    count.ticket ();
                    try {
    
    
                        Thread.sleep (100);
                    } catch (InterruptedException e) {
    
    
                        e.printStackTrace ();
                    }
                }
            }
        };
        t1.start ();
        t2.start ();
        t3.start ();
        t4.start ();
        t5.start ();
        t6.start ();
    }
}

思考:スレッドを作成するためのrun()とstart()の2つのメソッドの違いは何ですか?

おすすめ

転載: blog.csdn.net/guankunkunwd/article/details/121800637