Synchronized和Lock的区别

    科技2022-08-19  104

    Synchronized和Lock的区别

    1.原始构成

    Synchronized是Java中关键字属于jvm层, Synchronized底层是通过monitor对象完成的,可以用java -p命令查看汇编指令,其实wait、notify等方法也依赖于monitor对象因此可以直接this.wait调用。 Lock是具体类(java.util.concurrent.Locks.Lock)属于api层。

    2.使用方法:

    Synchronized不需要我们手动释放锁,ReentrantLock需要我们手动释放锁,如果没手动释放锁就会产生死锁。

    3.等待是否可中断:

    Synchronized不可以中断,除非正常运行完或者出异常。 ReentrantLock可以中断,可以设置超时方法tryLock(Long timeout,Timeunit unit);还可以调用interrupt()方法中断。

    4.加锁是否公平:

    Synchronized非公平锁 ReentrantLock在构造方法传入一个Boolean类型值true代表公平锁,什么也不传默认为不公平锁。

    5.绑定多个条件Condition

    Synchronized没有 ReentrantLock可以实现精确唤醒,而不像Synchronized要么随机唤醒一个要么唤醒全部。

    案例: 实现A线程打印5次,紧接着B线程打印10次,紧接着C线程打印15次,就是A–》B–》C,循环10次

    实现精确唤醒,线程轮番执行 代码如下:

    /** * 线程 操作(方法) 资源类 * 判断 干活 唤醒 * 避免假唤醒机制(while判断) */ class shareRasult{ //资源类 private int number = 1; //A1 B2 C3 private Lock lock= new ReentrantLock(); private Condition c1 =lock.newCondition(); //A private Condition c2 =lock.newCondition(); //B private Condition c3=lock.newCondition(); //C public void print5(){ lock.lock(); try{ while(number != 1){ c1.await(); } //干活 for(int i=1;i<=5;i++){ System.out.print(Thread.currentThread().getName()+i); } System.out.println(); //唤醒 number = 2; //更改标记位 c2.signal(); }catch (Exception e){ }finally { lock.unlock(); } } public void print10(){ lock.lock(); try{ while(number != 2){ c2.await(); } //干活 for(int i=1;i<=10;i++){ System.out.print(Thread.currentThread().getName()+i); } System.out.println(); //唤醒 number = 3; c3.signal(); }catch (Exception e){ }finally { lock.unlock(); } } public void print15(){ lock.lock(); try{ while(number != 3){ c3.await(); } //干活 for(int i=1;i<=15;i++){ System.out.print(Thread.currentThread().getName()+i); } System.out.println(); //唤醒 number = 1; c1.signal(); }catch (Exception e){ }finally { lock.unlock(); } } } 入口函数: public static void main(String[] args) { shareRasult shareRasult = new shareRasult(); new Thread(new Runnable() { @Override public void run() { for (int i=1;i<=10;i++){ shareRasult.print5(); } } },"A").start(); new Thread(new Runnable() { @Override public void run() { for (int i=1;i<=10;i++){ shareRasult.print10(); } } },"B").start(); new Thread(new Runnable() { @Override public void run() { for (int i=1;i<=10;i++){ shareRasult.print15(); } } },"C").start(); } //结果: A1A2A3A4A5 B1B2B3B4B5B6B7B8B9B10 C1C2C3C4C5C6C7C8C9C10C11C12C13C14C15 A1A2A3A4A5 B1B2B3B4B5B6B7B8B9B10 C1C2C3C4C5C6C7C8C9C10C11C12C13C14C15 A1A2A3A4A5 B1B2B3B4B5B6B7B8B9B10 C1C2C3C4C5C6C7C8C9C10C11C12C13C14C15 A1A2A3A4A5 B1B2B3B4B5B6B7B8B9B10 C1C2C3C4C5C6C7C8C9C10C11C12C13C14C15 A1A2A3A4A5 B1B2B3B4B5B6B7B8B9B10 C1C2C3C4C5C6C7C8C9C10C11C12C13C14C15 A1A2A3A4A5 B1B2B3B4B5B6B7B8B9B10 C1C2C3C4C5C6C7C8C9C10C11C12C13C14C15 A1A2A3A4A5 B1B2B3B4B5B6B7B8B9B10 C1C2C3C4C5C6C7C8C9C10C11C12C13C14C15 A1A2A3A4A5 B1B2B3B4B5B6B7B8B9B10 C1C2C3C4C5C6C7C8C9C10C11C12C13C14C15 A1A2A3A4A5 B1B2B3B4B5B6B7B8B9B10 C1C2C3C4C5C6C7C8C9C10C11C12C13C14C15 A1A2A3A4A5 B1B2B3B4B5B6B7B8B9B10 C1C2C3C4C5C6C7C8C9C10C11C12C13C14C15
    Processed: 0.008, SQL: 9