嘉兴北京网站建设,洛阳建设网站公司,不用代码做交互式网站,网站区域名怎么注册吗悲观锁 悲观#xff0c;则会假设情况总是最坏的#xff0c;即共同维护的数据总会被其他线程修改#xff0c;所以每次取数据的时候都会上锁#xff0c;避免其他人修改。 synchronized 关键字的实现也是悲观锁。 悲观锁的缺点 在多线程竞争下#xff0c;加锁、释放锁会导致… 悲观锁 悲观则会假设情况总是最坏的即共同维护的数据总会被其他线程修改所以每次取数据的时候都会上锁避免其他人修改。 synchronized 关键字的实现也是悲观锁。 悲观锁的缺点 在多线程竞争下加锁、释放锁会导致比较多的上下文切换和调度延时引起性能问题。 一个线程持有锁会导致其它所有需要此锁的线程挂起。 如果一个优先级高的线程等待一个优先级低的线程释放锁会导致优先级倒置引起性能风险。 synchronized 锁的形式
public static void main(String[] args) {MyThread t1 new MyThread(窗口一);MyThread t2 new MyThread(窗口二);t1.start();t2.start();
}//错误情况
Overridepublic void run() {while(count 0) {System.out.println(Thread.currentThread().getName()售出(count--) 票);try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}
//静态代码块上锁
Overridepublic void run() {while(count 0) {//静态代码块锁定义同一个对象synchronized (obj) {System.out.println(Thread.currentThread().getName()售出(count--) 票);}try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}//方法上锁public synchronized void increse() {System.out.println(Thread.currentThread().getName()售出(count--) 票);}Overridepublic void run() {while(count 0) {increse();try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}
//类上锁
synchronized(类名.Class) { //允许访问控制的代码
} 乐观锁 乐观则假设情况总是最好的即共同维护的数据不会被其他线程修改所以不会上锁即无锁。CAS(Compare and Swap)非阻塞性不存在死锁问题。没有锁竞争带来的系统开销也没有线程间频繁调度带来的开销具有更优越的性能。算法过程包含三个参数 CVS(V,E,N)。V表示要更新的变量E表示预期值N表示新值。仅当 V 值等于 E 值时才会将 V 的值设为 N 如果 V 值与 E 值不同则说明已经有其他线程做了更新则当前线程什么都不做。最后 CAS 返回当前 V 的真实值。当多个线程同时使用 CAS 操作一个变量时只有一个会胜出并成功更新其余均会失败。失败的线程不会挂起而是允许再次尝试。 lock锁 Lock 只是一个顶层抽象接口并没有实现也没有规定是乐观锁还是悲观锁实现规则。 ReentrantLock ReentrantReadWriteLock 。 ReentrantLock() ReentrantLock() 干了啥 public ReentrantLock() {sync new NonfairSync();} 在lock的构造函数中定义了一个NonFairSync static final class NonfairSync extends Sync NonfairSync 又是继承于Sync abstract static class Sync extends AbstractQueuedSynchronizer lock的存储结构一个int类型状态值用于锁的状态变更一个双向链表用于存储等待中的线程lock获取锁的过程本质上是通过CAS来获取状态值修改如果当场没获取到会将该线程放在线程等待链表中。lock释放锁的过程修改状态值调整等待链表。ReentrantReadWriterLock 通过两个内部类实现 Lock 接口分别是 ReadLock,WriterLock 类。它表示两个锁一个是读操作相关的锁称为共享锁一个是写相关的锁称为排他锁描述如下
线程进入读锁的前提条件 没有其他线程的写锁 没有写请求或者有写请求但调用线程和持有锁的线程是同一个。
线程进入写锁的前提条件 没有其他线程的读锁 没有其他线程的写锁
一、synchronized和lock的用法区别
synchronized在需要同步的对象中加入此控制synchronized可以加在方法上也可以加在特定代码块中括号中表示需要锁的对象。 lock需要显示指定起始位置和终止位置。一般使用ReentrantLock类做为锁多个线程中必须要使用一个ReentrantLock类做为对象才能保证锁的生效。且在加锁和解锁处需要通过lock()和unlock()显示指出。所以一般会在finally块中写unlock()以防死锁。lock只能写在代码里不能直接修改方法。
二、synchronized和lock性能区别 synchronized是托管给JVM执行的而lock是java写的控制锁的代码。 Java1.5中synchronize是性能低效的。因为这是一个重量级操作需要调用操作接口导致有可能加锁消耗的系统时间比加锁以外的操作还多。 Java1.6中synchronize在语义上很清晰可以进行很多优化有适应自旋锁消除锁粗化轻量级锁偏向锁等等。导致在Java1.6上synchronize的性能并不比Lock差。 性能不一样资源竞争激励的情况下lock性能会比synchronize好竞争不激励的情况下synchronize比lock性能好synchronize会根据锁的竞争情况从偏向锁--轻量级锁--重量级锁升级而且编程更简单。 锁机制不一样synchronize是在JVM层面实现的系统会监控锁的释放与否。lock是JDK代码实现的需要手动释放在finally块中释放。可以采用非阻塞的方式获取锁。 Synchronized的编程更简洁lock的功能更多更灵活缺点是一定要在finally里面 unlock()资源才行。 其他区别 1首先二者的关键字不同sync是关键字lock是接口。
2sync会主动释放锁lock不会而且容易产生死锁。
3sync默认是非公平锁悲观锁。Lock用的是乐观锁方式乐观锁实现的机制就是CAS操作。