Javaでスレッドセキュリティの問題を解決する2つの方法


一:コードブロックを同期する方法スレッドのセキュリティ問題(共有データ)を解決する
<スレッドを作成する方法がThreadクラスを継承する場合、同期コードブロック(ロック)を使用する場合、ロックの一意性を決定するために、オブジェクトをStaticタイプとして宣言する必要があります.
<スレッドを作成する方法がRunnableインタフェースを実現する方法であれば、直接オブジェクトを入れることができ、実現する方法でマルチスレッドを作成すること自体が同じオブジェクトを共有している.
  • 未ロック時のチケット販売プログラム(Threadクラスを継承する方式で作成されたマルチスレッド)
  • .
    public class WindowTest {
         
        public static void main(String[] args) {
         
            Window window = new Window();
            Window window1 = new Window();
            Window window2 = new Window();
            window.setName("   ");
            window1.setName("   ");
           window2.setName("   ");
           window.start();
           window1.start();
           window2.start();
        }
    }
    
    
    class Window extends Thread{
         
        private static int tickets=100;
    
    
        @Override
        public void run() {
         
           while(true){
         
               if (tickets>0){
         
                   System.out.println(Thread.currentThread().getName()+":  ,   :"+tickets);//
                   tickets--;
               }else{
         
                   break;
               }
           }
        }
    }
    
    
  • で重票が出る
  •    :  ,   :100
       :  ,   :100
       :  ,   :100
    
  • 同期コードブロックによりチケット問題(Threadクラスを継承するスレッド)
  • を解決する.
    class Window extends Thread{
         
        private static int tickets=100;
         static Object object=new Object();//  Thread                     
    
    
        @Override
        public void run() {
         
           while(true){
         
               synchronized(object){
         
               if (tickets>0){
         
                   try {
         
                       Thread.sleep(10);
                   } catch (InterruptedException e) {
         
                       e.printStackTrace();
                   }
                   System.out.println(Thread.currentThread().getName()+":  ,   :"+tickets);//
                   tickets--;
               }else{
         
                   break;
               }}
           }
        }
    }
    
  • 同期コードブロックによりチケット再発行問題(Runnableインタフェースを実現するために作成されたスレッド)
  • を解決する.
    public class WindowTest {
         
        public static void main(String[] args) {
         
    	 Windows windows = new Windows();
            Thread thread = new Thread(windows);//         windows  
            Thread thread1 = new Thread(windows);
            Thread thread2 = new Thread(windows);
            thread.setName("  1");
            thread1.setName("  2");
            thread2.setName("  3");
            thread.start();
            thread1.start();
            thread2.start();
        }
    }
    class Windows implements  Runnable{
         
    private  int tickets=100;
     Object object=new Object();
        @Override
        public void run() {
         
            while(true){
         
                synchronized (object){
         //          
                if (tickets>0){
         
        System.out.println(Thread.currentThread().getName()+":  ,   :"+tickets);//
                    tickets--;
                }else{
         
                    break;
                }
            }}
    
        }
    }
    

    二:同期方法によるスレッドセキュリティ問題の解決
    <共有データを操作するコードをsynchronizedキーワードで修飾する方法に置く
    <同じように、1つのスレッドが共有データを操作している場合、他のスレッドは絶対にアクセスできない同期方法の一意性を確保する必要があります.
    public class WindowTest02 {
         
        public static void main(String[] args) {
         
            Sole sole = new Sole();
            Thread thread = new Thread(sole);
            Thread thread1 = new Thread(sole);
            Thread thread2 = new Thread(sole);
            thread.setName("  1");
            thread1.setName("  2");
            thread2.setName("  3");
            thread.start();
            thread1.start();
            thread2.start();
    
        }
    }
    
    class Sole implements  Runnable{
         
        private static int  flags=100;
        @Override
        public void run() {
         
        while (true){
         
        show();
    
        }
    
        }
        public synchronized void show (){
         //
    
            if (flags>0){
         
                System.out.println(Thread.currentThread().getName()+"   "+flags);
                flags--;
    
            }
        }
    
    }