Synchronized 与 Lock 的使用

Synchronized的使用

        以卖票为例

//基本的卖票例子

/*
    真正的多线程开发,公司中的开发,降低耦合性
    线程就是一个单独的资源类,没有任何附属的操作
    1.属性、方法
 */
public class SaleTicketDemo01 {
    public static void main(String[] args) {
        //多个线程操作同一个资源类
        Ticket ticket = new Ticket();

        //@FunctionalInterface 函数式接口,jdk1.8 lambda表达式 (参数)->{ 代码 }
        new Thread(()->{
            for (int i = 0; i < 60; i++) {
                ticket.sale();
            }
        },"A").start();
        new Thread(()->{
            for (int i = 0; i < 60; i++) {
                ticket.sale();
            }
        },"B").start();
        new Thread(()->{
            for (int i = 0; i < 60; i++) {
                ticket.sale();
            }
        },"C").start();

    }

}

class Ticket {
    //属性、方法
    private int number = 50;

    //卖票的方式
    //synchronized 本质:队列,锁
    public synchronized void sale(){
        if (number>0){
            System.out.println(Thread.currentThread().getName()+"卖出了1张票,剩余"+--number+"张票");
        }
    }


}

Lock锁

        需要手动加锁,释放锁

  Lock锁是一个接口,他有三个实现类:

  • ReentrantLock类
  • ReentrantReadWriteLock.ReadLock
  • ReentrantReadWriteLock.WriteLock

        以卖票为例

//基本的卖票例子

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

/*
    真正的多线程开发,公司中的开发,降低耦合性
    线程就是一个单独的资源类,没有任何附属的操作
    1.属性、方法
 */
public class SaleTicketDemo02 {
    public static void main(String[] args) {
        //多个线程操作同一个资源类
        Ticket2 ticket = new Ticket2();

        //@FunctionalInterface 函数式接口,jdk1.8 lambda表达式 (参数)->{ 代码 }
        new Thread(()->{
            for (int i = 0; i < 5; i++) {
                ticket.sale();
            }
        },"A").start();
        new Thread(()->{
            for (int i = 0; i < 5; i++) {
                ticket.sale();
            }
        },"B").start();
        new Thread(()->{
            for (int i = 0; i < 5; i++) {
                ticket.sale();
            }
        },"C").start();

    }

}

class Ticket2 {
    //属性、方法
    private int number = 15;

    Lock lock = new ReentrantLock();

    //lock三部曲
    //1. new ReentrantLock()
    //2.lock.lock(); //加锁
    //3.finally =>lock.unlock(); //解锁
    public synchronized void sale(){

        lock.lock(); //加锁


        try {
            //业务代码
            if (number>0){
                System.out.println(Thread.currentThread().getName()+"卖出了1张票,剩余"+--number+"张票");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();  //解锁
        }
    }

}

Lock锁和synchronized的区别

  1. Synchronized是内置Java关键字;Lock是一个Java类。
  2. Synchronized无法判断获取锁的状态;Lock可以判断是否获取到了锁。(boolean b = lock.tryLock();)
  3. Synchronized会自动释放锁;Lock必须要手动释放锁,如果不释放锁,死锁。
  4. Synchronized线程1获得锁阻塞时,线程2会一直等待下去;Lock锁线程1获得锁阻塞时,线程2等待足够长的时间后中断等待,去做其他的事。
  5. Synchronized可重入锁,不可以中断的,非公平;Lock,可重入锁,可以判断锁,非公平(可手动设置为公平锁)。
  6. Synchronized适合锁少量的代码同步问题;Lock适合锁大量的同步代码。

猜你喜欢

转载自blog.csdn.net/weixin_48426115/article/details/127895248
今日推荐