底层知识二

底层知识二,第1张

底层知识二 1. synchronized 与 Lock的区别及底层实现 1).synchronized(以下用sync表示)与lcok区别?
  1. 来源及用法:

    lock是一个接口,是java写的控制锁的代码,而synchronized是java的一个内置关键字,synchronized是托管JVM执行的。

    synchronized:在需要同步的对象中加入此控制,synchronized可以家在方法上,也可以加在特定代码块中,括号中标识需要锁的对象。

    lock:一般使用ReentrantLock类作为锁。在加锁和解锁处需要通过lock()和unlock()显示指出。

    所以一般不会在finally块中写unlock()以防死锁。

  2. 异常是否释放锁:

    synchronized在发生异常时候会自动释放占有的锁,因此不会出现死锁,而lock发生异常时候,不会主动释放占有的锁。必须手动unlock来释放锁,可能引起死锁的发生。

    所以最好将同步代码块用try catch抱起来,finally 中写入unlock,避免死锁的发生。)

  3. 是否响应中断

    lock等待锁过程中可以用interrupt来中断等待,而synchronized只能等待锁的释放,不能响应中断。

  4. 是否阻塞

    Lock可以尝试获取锁,synchronized获取不到锁只能一直阻塞;synchronized关键字的两个线程1和线程2,如果当前线程1获得锁,线程2线程等待。如果线程1阻塞,线程2则会一直等待下去,而Lock锁就不一定会等待下去,如果尝试获取不到锁,线程可以不用一直等待就结束了;

  5. 锁特点

    synchronized的锁可重入、不可中断、非公平,而Lock锁可重入、等待时可中断、可判断、可公平可非公平

  6. 性别差别

    1.在Java1.5中,synchronize时性能低效的。因为这是一个重量级 *** 作,需要调用 *** 作接口,导致有可能枷锁的系统事件比枷锁意外的 *** 作还多。相比之下使用Java提供的Lock对象,性能更高一些,但是到了jAVA1.6发生了变化。synchronize在语义上很清晰,可以进行很多优化,有适应自旋,锁消除,锁粗化,轻量级锁,偏向锁等等。导致在Java1.6上synchronize的性能并不比Lock差。

    使用场景:

    竞争资源不激烈,两者的性能是差不多的,而当竞争资源非常激烈时,此时Lock可以提高多个线程进行读写 *** 作的效率

  7. 等待通知

    synchronized使用Object对象本身的wait、notify、notifyAll调度机制,而Lock可以使用

    Condition进行线程之间的调度

  8. 锁机制

    1.synchronized原始采用的时CPU悲观锁机制,即线程获得的时独占锁,独占锁意味着其他线程只能依靠阻塞来等待线程释放锁。而在CPU转换线程阻塞时会引起线程上下文切换。当有很多线程竞争锁的时候,会引起CPU频繁的上下文切换导致效率很低

    2.Lock用的是乐观锁方式。所谓乐观锁就是,每次不加锁而是假设没有冲突而去完成某项 *** 作,如果因为冲突失败就重试,直到成功为止。

    乐观锁实现机制是CAS *** 作。

现代的CPU提供了指令,可以自动更新共享数据,而且能够检测到其他线程的干扰,而compareAntSet()就用这些代替了锁定。这个算法成做非阻塞算法,意思是一个线程的失败或者挂起,不应该影响其他线程的失败或者挂起的算法。

2). synchronized 实现原理

Java中每一个对象都可以作为锁,这是synchronized实现同步的基础:

  1. 普通同步方法,锁是当前实例对象

  2. 静态同步方法,锁是当前类的class对象

  3. 同步方法块,锁是括号里面的对象

本文链接:https://blog.csdn.net/wangnanwlw/article/details/109243637

2. Lock 方法
  • Lock();//获取锁
  • tryLock();//获取锁
  • tryLock(long time,TimeUnit unit);//在一定事件单位内等待
  • lockInterruptibly();//获取锁,可响应中断(AB线程同时获取锁,A得到后,B进行等待,则B会被Thread.interrupt()方法中端并可去执行其他的代码逻辑,而synchronized无法被中断
  • unlock();//释放锁 在finally里释放锁
3. synchronized 是非公平锁,即不能保证等待锁线程的顺序

Lock的实现 ReentrantLock 可通过实例化 true or false 的构造参数实现公平锁和非公平锁,默认为非公平锁。

4. ReenteantLock 是唯一实现了Lock接口的类,并且ReentrantLock提供了更多的方法
lck.isFair();
lck.isLocked();
lck.getHoldCount();
lck.getQueueLength();
lck.wait();
...
5. synchronized 无法判断是否获取锁的状态,Lock 可以判断是否获取到锁; 6. Lock锁适合大量同步的代码的同步问题,synchronized锁适合代码少量的同步问题 7. 都是可重入锁:在执行对象中所有同步方法不用再次获得锁 8. synchronized 是一个悲观锁,Lock是一个乐观锁 底层基于volatile和cas实现 二、 底层实现 1. synchronznized 映射成字节码指令 就是 增加两个指令:monitorenter、monitorexit

​ 当一个线程执行时遇到monitorenter指令时,它会尝试去获得锁,如果获得锁,那么所计数器+1(为什么加1,因为它时可重入锁,可根据这个锁计数器判断锁状态),如果没有获得锁,那么阻塞,当他遇到一个monitoerexit时,锁计数器会-1,当计数器为0时,就释放锁

2. Lock底层则基于volatile和cas实现 三、 java netty 客户端突然断电服务端无法监听到?

java netty 框架实现异步的、事件驱动的网络应用程序框架和工具。其中在实现ChannellnboundHandlerAdapter接口的类会自动实现的它的channelActive和channellNactive方法。这两个方法分别时当客户端连接服务端后和客户端断开后会调用此方法。现在第二个方法,当客户端突然断电后服务端并不会调用channellnative方法。如果服务端不能监听到客户端因为断电而掉线,就无法更新设备的在线状态。

服务端用的时netty框架,而我的客户端用到的时硬件设备。服务端开启后,硬件会自动去连接服务器,实现通信。但是硬件突然关闭或者断电,服务端不能检测到客户端掉线了

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/4019377.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-10-22
下一篇 2022-10-22

发表评论

登录后才能评论

评论列表(0条)

保存