JUC之Lock接口

1.synchronized與Lock的區別
(1)synchronized是java內置關鍵字,在jvm層面,Lock是個java類
(2)synchronized無法判斷是否獲取鎖的狀態,Lock可以判斷是否獲取到鎖
(3)synchronized會自動釋放鎖(a線程執行完同步代碼會釋放鎖,b線程執行過程中發生異常會釋放鎖),Lock需要在finally中手動釋放鎖(unlock()方法釋放鎖),否則容易造成線程死鎖
(4)用synchronized關鍵字的兩個線程1和線程2,如果當前線程1獲得鎖,線程2等待,如果線程1阻塞,線程2會一直等待下去;而Lock鎖就不一定會等待下去,如果嘗試獲取不到鎖,線程可以不用一直等待就結束了了
(5)synchronized的鎖可重入、不可中斷、非公平,而Lock鎖可重入、可判斷、可公平
(6)Lock鎖適合大量代碼的同步問題,synchronized鎖適合少量代碼的同步問題

package com.alisa.juc;

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

class Tocket{  //資源類 = 實例變量 + 實例方法,線程操作資源類
    private int number = 30;
    Lock lock = new ReentrantLock();

    public void sale(){
        lock.lock();
        try{
            if(number > 0){
                System.out.println(Thread.currentThread().getName() + "賣出第" + (number--) +"張票,還剩" + number +"張");
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }
}

public class LockTest {
    public static void main(String[] args) {  //主線程,一切程序的入口
        Tocket tocket = new Tocket();
        //使用匿名內部類
        /*new Thread(new Runnable() {
            @Override
            public void run() {
                for(int i=0; i<40; i++){
                    tocket.sale();
                }
            }
        }, "A").start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                for(int i=0; i<40; i++){
                    tocket.sale();
                }
            }
        }, "B").start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                for(int i=0; i<40; i++){
                    tocket.sale();
                }
            }
        }, "C").start();*/

        //使用Lambda表達式
        new Thread(() -> {
            for (int i = 0; i < 40; i++) {
                tocket.sale();
            }
        }, "A").start();

        new Thread(() -> {
            for (int i = 0; i < 40; i++) {
                tocket.sale();
            }
        }, "B").start();

        new Thread(() -> {
            for (int i = 0; i < 40; i++) {
                tocket.sale();
            }
        }, "C").start();
    }
}

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