07_多線程之間共享數據

  1. 如果每個線程執行代碼相同,可以使用同一個Runnable對象,這個Runnable對象中有共享數據,eg:買票系統;
    public class SellTicket {
        public static void main(String[] args) {
            TicketWindow ticketWindow = new TicketWindow();
            for (int i=0;i<4;i++){//4個線程,相當於4個售票窗口
                new Thread(ticketWindow).start();
            }
    
        }
    }
    
    class TicketWindow implements Runnable{
    
        private int count = 100;//100張票
        @Override
        public void run() {
            while (true){
                sellTicket();
            }
        }
    
        private synchronized void sellTicket() {
            if(count>0){
                count--;
                System.out.println(Thread.currentThread().getName()+" 賣出一張票,還有"+count+"張票");
            }else{
                System.out.println("票已賣完...");
            }
        }
    }
  2. 如果每個線程執行代碼不同,這個時候需要使用不同的Runnable,有一下兩種方式實現Runnable對象之間的數據共享:
    1. 將共享對象封裝到另一個對象中,並將對象傳給Runnable對象
      //-
      class ShareData {
          //共享對象
          private int j = 0;
          //+
          public synchronized void increment(){
              j++;
          }
          //-
          public synchronized void decrement(){
              j--;
          }
      }
      
      //+
      class MyRunnable1 implements Runnable{
          private ShareData shareData;
          public MyRunnable1(ShareData shareData){
              this.shareData = shareData;
          }
          @Override
          public void run() {
              while (true){
                  shareData.increment();
              }
          }
      }
      //-
      class MyRunnable2 implements Runnable{
          private ShareData shareData;
          public MyRunnable2(ShareData shareData){
              this.shareData = shareData;
          }
          @Override
          public void run() {
              while (true){
                  shareData.decrement();
              }
          }
      }
      //使用
      public static void main(String[] args) {
          ShareData data = new ShareData();
          new Thread(new MyRunnable1(data)).start();
          new Thread(new MyRunnable2(data)).start();
      }
    2. 將Runnable對象作爲某個對象的內部類,共享數據作爲該外部類的成員變量
      class ShareData {
          //共享對象
          private int j = 0;
          //+
          public synchronized void increment(){
              j++;
          }
          //-
          public synchronized void decrement(){
              j--;
          }
      }
      
      //使用
      public static void main(String[] args) {
          ShareData data = new ShareData();
          new Thread(new MyRunnable(){
              data.increment();
          }).start();
          new Thread(new MyRunnable(){
              data.decrement();
          }).start();
      }
      1. 這兩種方式的組合:將共享數據封裝到另外一個對象中,對象作爲外部類外部類的成員變量或者方法中的局部變量,

    3.  每個線程的Runnable對象作爲外部類的成員內部類或者局部內部類。

            兩個內部類共享數據:兩個內部類,共享數據做外部類的成員變量

      1、賣票系統

      2、面試題:

           設計4個線程,其中兩個線程每次對j增加1,另外兩個線程對j每次減少1   

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章