解決方法三:lock鎖機制

clipboard.png

clipboard.png
package com.itheima.demo09.Lock;java

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;安全

/*多線程

賣票案例出現了線程安全問題
賣出了不存在的票和重複的票

解決線程安全問題的三種方案:使用Lock鎖
java.util.concurrent.locks.Lock接口
Lock 實現提供了比使用 synchronized 方法和語句可得到的更普遍的鎖定操做。
Lock接口中的方法:
    void lock()獲取鎖。
    void unlock()  釋放鎖。
java.util.concurrent.locks.ReentrantLock implements Lock接口


使用步驟:
    1.在成員位置建立一個ReentrantLock對象
    2.在可能會出現安全問題的代碼前調用Lock接口中的方法lock獲取鎖
    3.在可能會出現安全問題的代碼後調用Lock接口中的方法unlock釋放鎖

*/
public class RunnableImpl implements Runnable{ide

//定義一個多個線程共享的票源
private  int ticket = 100;

//1.在成員位置建立一個ReentrantLock對象
Lock l = new ReentrantLock();

//設置線程任務:賣票
@Override
public void run() {
    //使用死循環,讓賣票操做重複執行
    while(true){
        //2.在可能會出現安全問題的代碼前調用Lock接口中的方法lock獲取鎖
        l.lock();

        //先判斷票是否存在
        if(ticket>0){
            //提升安全問題出現的機率,讓程序睡眠
            try {
                Thread.sleep(10);
                //票存在,賣票 ticket--
                System.out.println(Thread.currentThread().getName()+"-->正在賣第"+ticket+"張票");
                ticket--;
            } catch (InterruptedException e) {
                e.printStackTrace();
            }finally {
                //3.在可能會出現安全問題的代碼後調用Lock接口中的方法unlock釋放鎖
                l.unlock();//不管程序是否異常,都會把鎖釋放
            }
        }
    }
}

/*//設置線程任務:賣票
@Override
public void run() {
    //使用死循環,讓賣票操做重複執行
    while(true){
       //2.在可能會出現安全問題的代碼前調用Lock接口中的方法lock獲取鎖
       l.lock();

        //先判斷票是否存在
        if(ticket>0){
            //提升安全問題出現的機率,讓程序睡眠
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            //票存在,賣票 ticket--
            System.out.println(Thread.currentThread().getName()+"-->正在賣第"+ticket+"張票");
            ticket--;
        }

        //3.在可能會出現安全問題的代碼後調用Lock接口中的方法unlock釋放鎖
        l.unlock();
    }
}*/

}
package com.itheima.demo09.Lock;spa

/*線程

模擬賣票案例
建立3個線程,同時開啓,對共享的票進行出售

*/
public class Demo01Ticket {code

public static void main(String[] args) {
    //建立Runnable接口的實現類對象
    RunnableImpl run = new RunnableImpl();
    //建立Thread類對象,構造方法中傳遞Runnable接口的實現類對象
    Thread t0 = new Thread(run);
    Thread t1 = new Thread(run);
    Thread t2 = new Thread(run);
    //調用start方法開啓多線程
    t0.start();
    t1.start();
    t2.start();
}

}對象

相關文章
相關標籤/搜索