JAVA多線程 & 同步關鍵詞synchronized & ReadWriteLock讀寫檔案

來源:互聯網
上載者:User

標籤:nts   適合   system   問題:   hex   兩種   static   獨立   覆寫   

  在java中可有兩種方式實現多線程,一種是繼承Thread類,一種是實現Runnable介面;Thread類是在java.lang包中定義的。一個類只要繼承了Thread類同時覆寫了本類中的run()方法就可以實現多線程操作了,但是一個類只能繼承一個父類,這是此方法的局限。

1 public class Actor extends Thread  {2     public void run(){3          //線程執行的操作4         }5 }   

  在實際開發中一個多線程的操作很少使用Thread類,而是通過Runnable介面完成。

1 public class Actress implements Runnable{2 3     @Override4     public void run() {5         //線程執行的操作6         }7 }    

  在主方法中調用這兩種線程。

1     public static void main(String[] args) {2         Thread actor=new Actor();3         actor.setName("Mr.thread");  //Thread 線程4         actor.start();5         6         Thread actressThread=new Thread(new Actress(),"Miss.Runnable");  //Runnable 線程7         actressThread.start();8     }

 

兩種實現方式的區別和聯絡:

  在程式開發中只要是多線程肯定永遠以實現Runnable介面為主,因為實現Runnable介面相比繼承Thread類有如下好處:

    1、避免點繼承的局限,一個類可以繼承多個介面。

    2、適合於資源的共用

  以賣票程式為例,通過Thread類完成:

 1 package multithreading; 2  3 public class MyThreadWithExtends extends Thread { 4  5     private int tickets = 10; 6  7     @Override 8     public void run() { 9 10         for (int i = 0; i <= 100; i++) {11             if(tickets>0){12                 System.out.println(Thread.currentThread().getName()+"--賣出票:" + tickets--);13             }14         }15     }16     17     18     public static void main(String[] args) {19         MyThreadWithExtends thread1 = new MyThreadWithExtends();20         MyThreadWithExtends thread2 = new MyThreadWithExtends();21         MyThreadWithExtends thread3 = new MyThreadWithExtends();22 23         thread1.start();24         thread2.start();25         thread3.start();26         27         //每個線程都獨立,不共用資源,每個線程都賣出了10張票,總共賣出了30張。如果真賣票,就有問題了。28     }29 30 }

運行結果:

  Thread-0--賣出票:10
  Thread-2--賣出票:10
  Thread-1--賣出票:10
  Thread-2--賣出票:9
  Thread-0--賣出票:9
  Thread-2--賣出票:8
  Thread-1--賣出票:9
  Thread-2--賣出票:7
  Thread-0--賣出票:8
  Thread-2--賣出票:6
  Thread-2--賣出票:5
  Thread-2--賣出票:4
  Thread-1--賣出票:8
  Thread-2--賣出票:3
  Thread-0--賣出票:7
  Thread-2--賣出票:2
  Thread-2--賣出票:1
  Thread-1--賣出票:7
  Thread-0--賣出票:6
  Thread-1--賣出票:6
  Thread-0--賣出票:5
  Thread-0--賣出票:4
  Thread-1--賣出票:5
  Thread-0--賣出票:3
  Thread-1--賣出票:4
  Thread-1--賣出票:3
  Thread-1--賣出票:2
  Thread-0--賣出票:2
  Thread-1--賣出票:1
  Thread-0--賣出票:1

 

  如果用Runnable就可以實現資源共用,下面看例子:

 1 package multithreading; 2  3 public class MyThreadWithImplements implements Runnable { 4  5     private int tickets = 10; 6  7     @Override 8     public void run() { 9 10         for (int i = 0; i <= 100; i++) {11             if(tickets>0){12                 System.out.println(Thread.currentThread().getName()+"--賣出票:" + tickets--);13             }14         }15     }16     17     18     public static void main(String[] args) {19         MyThreadWithImplements myRunnable = new MyThreadWithImplements();20         Thread thread1 = new Thread(myRunnable, "視窗一");21         Thread thread2 = new Thread(myRunnable, "視窗二");22         Thread thread3 = new Thread(myRunnable, "視窗三");23 24         thread1.start();25         thread2.start();26         thread3.start();27     }28 29 }

運行結果:

  視窗二--賣出票:10
  視窗三--賣出票:9
  視窗一--賣出票:8
  視窗三--賣出票:6
  視窗三--賣出票:4
  視窗三--賣出票:3
  視窗三--賣出票:2
  視窗三--賣出票:1
  視窗二--賣出票:7
  視窗一--賣出票:5

每個線程共用了對象myRunnable的資源,賣出的總票數是對的,但是順序是亂的,怎麼辦?

 

同步關鍵詞synchronized 

線程執行的時候,一個個執行不就有序了。即線程1在執行的時候,其他線程阻塞不要執行。

加synchronize。

 1 package multithreading.sync; 2  3 public class MyThreadWithImplements implements Runnable { 4  5     private int tickets = 10; 6  7     @Override 8     public synchronized void run() { 9             //同步關鍵詞synchronized10         for (int i = 0; i <= 100; i++) {11             if(tickets>0){12                 System.out.println(Thread.currentThread().getName()+"--賣出票:" + tickets--);13             }14         }15     }16     17     18     public static void main(String[] args) {19         20         MyThreadWithImplements myRunnable = new MyThreadWithImplements();21         Thread thread1 = new Thread(myRunnable, "視窗一");22         Thread thread2 = new Thread(myRunnable, "視窗二");23         Thread thread3 = new Thread(myRunnable, "視窗三");24 25         thread1.start();26         thread2.start();27         thread3.start();28     }29 30 }

運行結果

  視窗一--賣出票:10
  視窗一--賣出票:9
  視窗一--賣出票:8
  視窗一--賣出票:7
  視窗一--賣出票:6
  視窗一--賣出票:5
  視窗一--賣出票:4
  視窗一--賣出票:3
  視窗一--賣出票:2
  視窗一--賣出票:1

 

缺陷

  1、如果這個擷取鎖的線程由於要等待IO或者其他原因(比如調用sleep方法)被阻塞了,但是又沒有釋放鎖,其他線程便只能乾巴巴地等待,這多麼影響程式執行效率。


  2、當有多個線程讀寫檔案時,讀寫操作會發生衝突現象,寫操作會發生衝突現象,但是讀操作不會發生衝突現象。但是採用synchronized關鍵字來實現同步的話,就會導致一個問題:如果多個線程都只是進行讀操作,當一個線程在進行讀操作時,其他線程只能等待無法進行讀操作。


  因此就需要一種機制來使得多個線程都只是進行讀操作時,線程之間不會發生衝突,通過Lock就可以辦到。另外,通過Lock可以知道線程有沒有成功擷取到鎖。這個是synchronized無法辦到的。總的來說,也就是說Lock提供了比synchronized更多的功能。

ReadWriteLock讀寫檔案概述

ReadWriteLock是一個介面,在它裡面只定義了兩個方法:一個讀的鎖和一個寫的鎖。

讀的鎖:A線程擷取了讀的鎖,那麼B線程也可以擷取讀的鎖。

寫的鎖:A線程擷取了寫的鎖,那麼B線程不能擷取讀也不能擷取寫的鎖。

 1 public interface ReadWriteLock {   2     /**  3      * Returns the lock used for reading.  4      * 讀的鎖,A線程擷取了讀的鎖,那麼B線程也可以擷取讀的鎖  5      * @return the lock used for reading.  6      */   7     Lock readLock();   8     9     /** 10      * Returns the lock used for writing. 11      * 寫的鎖,A線程擷取了寫的鎖,那麼B線程不能擷取讀也不能擷取寫的鎖。 12      * @return the lock used for writing. 13      */  14     Lock writeLock();  15 } 

。。。未完待續

 

JAVA多線程 & 同步關鍵詞synchronized & ReadWriteLock讀寫檔案

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.