多線程之 安全執行緒

來源:互聯網
上載者:User

標籤:關鍵字   err   unlock   sleep   成員   zed   其他   tca   color   

一.安全執行緒出現原因:

  原因:  原本不應該拆開的兩個步驟中間,被其他線程插足。

  解決方案:(java中的同步機制 [synchronized] 來解決),具體有下面三種
          a. 同步代碼塊
          b. 同步方法
          c. Lock介面
              建立:Lock lock = new ReentrantLock();
              霸佔鎖:lock();
              釋放鎖:unlock();

  代碼示範安全執行緒問題:

public class Ticket implements Runnable{    //定義一個成員變數,表示還有多少張票    int num = 100;    //要在run方法中定義賣票的任務    @Override    public void run() {        //因為要一直賣票,所以使用死迴圈        while (true) {            //如果還有票,那麼就賣票            if(num > 0) {                try {                    Thread.sleep(20);                } catch (InterruptedException e) {                }                System.out.println(Thread.currentThread().getName() + "正在賣票:" + num);                num--;            }        }    }}

 

public class Demo01TicketTest {    public static void main(String[] args) {        //建立三個線程,執行這個賣票任務        Ticket t = new Ticket();        //等同於建立了3個視窗,每個視窗都執行一樣的任務:售票        new Thread(t).start();        new Thread(t).start();        new Thread(t).start();    }}

   上面代碼Demo01TicketTest,運行後可在控制台查看:

      1.出現了票 0 ,-1

      2.還有售出重複的票

  這就是多個線程會出現的安全執行緒問題,而在現實中這是不允許的

二.解決安全執行緒的同步代碼塊方法

  同步代碼塊: synchronized關鍵字可以用於方法中的某個區塊中,表示支隊這個區塊的資源實行互斥訪問

  格式: synchronized( 同步鎖 ){

       需要同步操作的代碼

     }

  同步鎖: 對象的同步鎖知識一個概念,就是個標記,(就好像獅子佔地盤,撒了尿這就是我的地盤)

      1. 鎖對象,可以是任意類型

      2. 多個線程對象,要使用同一把鎖

  注意:  一個同步鎖最多被一個線程鎖擁有,誰拿到鎖就可以進入代碼塊,其他的線程只能外面等待,等待同步鎖被上一個線程釋放後,再進行搶佔cpu

  使用此方法解決,上面多線程售票安全問題

public class Ticket implements Runnable{    int num = 100;    //定義一個對象,這個對象表示鎖對象    //鎖對象沒有特殊的含義,只是做一個標記    //多個線程必須使用同一個鎖對象,否則不能保證安全執行緒。    Object lock = new Object();    @Override    public void run() {        while (true) {            //當線程執行到synchronized這句代碼的時候,會看一下這個上面還有沒有鎖            //如果同步代碼塊上面還有鎖,那麼線程就擷取到這個鎖, 然後進入到同步代碼塊中。            //如果同步代碼塊上面沒有鎖, 那麼這個線程就一直在這個位置等著擷取鎖, 如果鎖一直不來,那麼就一直等著.            synchronized (lock) {                if(num > 0) {                    try {                        Thread.sleep(20);                    } catch (InterruptedException e) {                    }                    System.out.println(Thread.currentThread().getName() + "正在賣票:" + num);                    num--;                }            }            //當一個線程離開同步代碼塊,那麼他會釋放鎖。            //之後其他線程就可以去競爭這個鎖,誰搶到了,那麼誰就去執行這個同步代碼塊。        }    }}
 三.解決安全執行緒的同步方法方法

  同步方法: 使用synchronized修飾的方法,就叫做同步方法,保證A線程執行該方法的時候,其他線程只能在方法外面等著

  格式:  public synchronized void method(){

        可能會產生安全執行緒問題的代碼

      }

  注意:  同步方法中也有同步鎖

        對於非static方法,同步鎖就是this,

        對於static方法,同步鎖是類名.class (我們使用當前方法所在類的位元組碼對象)

  使用同步方法代碼解決售票的安全執行緒問題:

package cn.itcast.demo02;@SuppressWarnings("all")public class Ticket implements Runnable{    int num = 100;    @Override    public void run() {        while (true) {            sell();        }    }    //同步方法,表示對整個方法體都加上了同步代碼塊    public synchronized void sell() {        if(num > 0) {            try {                Thread.sleep(20);            } catch (InterruptedException e) {            }            System.out.println(Thread.currentThread().getName() + "正在賣票:" + num);            num--;        }    }}
 四.解決安全執行緒的Lock介面方法

  Lock鎖: lock機制提供了比synchronized代碼塊和synchronized方法更加廣泛的操作

       Lock,更加強大,更加體現物件導向

  Lock鎖也成為同步鎖,將加鎖和釋放所拆分兩個方法,如下:

     public void lock(): 加同步鎖

     public void unlock(): 釋放同步鎖

  使用該方法解決多線程售票安全問題

public class Ticket4 implements Runnable{    int num = 100;    //建立Lock對象    Lock lock = new ReentrantLock();    @Override    public void run() {        while (true) {            //調用lock對象的lock()方法,手動的擷取鎖            lock.lock();            if(num > 0) {                try {                    Thread.sleep(20);                } catch (InterruptedException e) {                }                System.out.println(Thread.currentThread().getName() + "正在賣票:" + num);                num--;            }            //調用lock對象的unlock方法,手動的釋放鎖            lock.unlock();        }    }}

 

 

 

 

 

 

 

 

 

 

  

 

多線程之 安全執行緒

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.