Java學習筆記45(多線程二:安全問題以及解決原理),java學習筆記

來源:互聯網
上載者:User

Java學習筆記45(多線程二:安全問題以及解決原理),java學習筆記

安全執行緒問題以及解決原理:

多個線程用一個共用資料時候出現安全問題

 

一個經典案例:

電影院賣票,共有100座位,最多賣100張票,買票方式有多種,網上購買、自主售票機、排隊購買

三種方式操作同一個共用資料,這時候會出現安全問題:

樣本:

package demo1;public class Tickets implements Runnable {    private int ticket = 100;        public void run(){        while(true){            if (ticket>0) {                System.out.println(Thread.currentThread().getName()+"出售第"+ticket--+"張票");            }        }    }}
package demo1;public class ThreadDemo {    public static void main(String[] args) {        Tickets t = new Tickets();        Thread t0 = new Thread(t);        Thread t1 = new Thread(t);        Thread t2 = new Thread(t);        t0.start();        t1.start();        t2.start();    }}

一般不會出現問題,但是要想到這種問題

但是,假設只剩下最後最後一張票,一個線程搶到CPU資源執行,在判斷結束時候,CPU資源被其他線程搶到,其他線程判斷然後執行,

這時候輪到開始時候的線程,由於已經判斷完,繼續執行,這時候票數就會變成負數,這裡就出現了問題

 

解決方案:

同步代碼塊

原理:一個線程進入資料操作的時候,阻止其他線程執行

package demo1;public class Tickets implements Runnable {    private int ticket = 100;    private Object obj1 = new Object();    public void run() {        while (true) {            synchronized (obj1) {                if (ticket > 0) {                    System.out.println(Thread.currentThread().getName() + "出售第" + ticket-- + "張票");                }            }        }    }}

不過,雖然安全了,但是運行速度下降

但是,我們為了安全性可以不顧及速度,無論如何都要保證安全性

 

這裡傳入的對象參數簡稱作:同步鎖,專業名稱:對象監視器

原理:

沒有鎖的線程不能執行,只能等待

線程遇到同步代碼塊後判斷是否有同步鎖,如果有,拿走鎖,進入同步中執行,執行完畢後將鎖對象還回去

另一個線程遇到代碼塊後沒有鎖,無法進入,原來的線程把鎖還回去之後新線程再擷取鎖,迴圈下去

 

這裡明顯可以看出,這麼多的過程,速度自然就慢下來了

 

採用同步方法解決問題:

優點:代碼量更低

package demo1;public class Tickets implements Runnable {    private int ticket = 100;        public void run() {        while (true) {            payTicket();        }    }    public synchronized void payTicket() {        //同步方法的對象鎖是本類對象引用:即為this        //靜態方法的鎖是本類類名.class        if (ticket > 0) {            System.out.println(Thread.currentThread().getName() + "出售第" + ticket-- + "張票");        }    }}

 缺點:如果出現了異常,方法的鎖對象沒有釋放,不出同步,鎖不會釋放

 

這裡就需要用到一個Lock介面:

提供了更廣泛的鎖定操作

 

改進之前的售票案例:

package demo1;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;public class Tickets implements Runnable {    private int ticket = 100;    private Lock lock = new ReentrantLock();    public void run() {        while (true) {            lock.lock();            if (ticket > 0) {                System.out.println(Thread.currentThread().getName() + "出售第" + ticket-- + "張票");            }            lock.unlock();        }    }}

 

死結:

同步鎖引發的弊端:

當線程任務中出現了多個同步時,如果同步中嵌套了其他的同步,這時候就會引發一種現象,程式出現無限等待,這種現象稱之為死結

通俗解釋:兩個人吃一碗面,卻只有一雙筷子,兩個人一人搶到一支筷子,規定不能用手抓,這時候就無法吃面

代碼實現:

package demo1;public class LockA {    private LockA(){}        public final static LockA locka =new LockA();}
package demo1;public class LockB {    private LockB(){}        public final static LockB lockb =new LockB();}
package demo1;public class DeadLock implements Runnable {    private int i = 0;    public void run() {        while (true) {            if (i % 2 == 0) {                synchronized (LockA.locka) {                    System.out.println("if...locka");                    synchronized (LockB.lockb) {                        System.out.println("if...lockb");                    }                }            } else {                synchronized (LockB.lockb) {                    System.out.println("else...lockb");                    synchronized (LockA.locka) {                        System.out.println("else...locka");                    }                }            }            i++;        }    }}
package demo1;public class DeadLockDemo {    public static void main(String[] args) {        DeadLock dead = new DeadLock();        Thread t0 = new Thread(dead);        Thread t1 = new Thread(dead);        t0.start();        t1.start();    }}

運行後發現,會卡在某一處不動,但是並沒有停止

 

聯繫我們

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