Java多线程之synchronized与Lock
来源:互联网 发布:java将图片生成二维码 编辑:程序博客网 时间:2024/05/22 01:09
首先我们需要先理解一下什么是共享受限资源。
private int currentEvenValue = 0;public int next() { ++currentEvenValue;//++I表示先自增在赋值,I++表示先赋值在自增 //Thread.yield(); ++currentEvenValue; return currentEvenValue;}我们来看下这段代码,在多线程环境下,一个线程可能在另外一个线程刚刚执行完第一行++currentEvenValue的时候调用next方法,此时就会造成读取的currentEvenValue变量的值不正确,造成程序错误甚至崩溃,当然这个可能是一个小概率事件,但是根据墨菲定律,可能会出现的就一定会出现。大家可以自己测试下,为了更快的发现,我们可以使用Thread.yield()来快速发现失败。
为了解决这个冲突,Java内置了synchronized关键字来解决资源冲突。在Java中所有的对象都含有单一的锁(监视器),当在对象上调用任意声明为synchronized的方法的时候,,此对象都会被加锁,这时此对象的别的synchronized方法就只有等前一个方法再执行完毕并释放锁之后才能被调用。简单点来说,就是某个对象的所有synchronized方法共享同一个锁。
注意:在使用synchronized时要将域设置为private,否则synchronized无法阻止其他任务直接访问从而产生冲突。
一个任务可以多次获得对象的锁,如果一个方法在同一个对象上调用了另外的synchronized方法就会发生这种情况。jvm负责跟踪对象被枷锁的次数,在任务第一次给对象加锁的时候,计数为1,当这个任务再次获得锁时,计数会递增,每当任务离开一个synchronized方法计数会递减,当计数为0时锁被完全释放。每个类也有一个锁,作为类的Class对象的一部分,所以synchronized static方法可以再类的范围内防止对static数据的并发访问。
说了这么多,贴下对上述问题的解决代码:
private int currentEvenValue = 0;public synchronized int next() { ++currentEvenValue;//++I表示先自增在赋值,I++表示先赋值在自增 Thread.yield(); ++currentEvenValue; return currentEvenValue;}针对上一问题,我们也可以使用显式的Lock对象来加锁。
private Lock lock = new ReentrantLock();public int anotherNext(){ lock.lock();//枷锁 try { ++currentEvenValue; Thread.yield(); ++currentEvenValue; return currentEvenValue; }finally{ lock.unlock();//释放锁 }在这里需要注意的需要注意的是如果需要继续调用lock方法,必须放置在带有unlock()的try-finally子句中,还有就是return必须在try子句中出现,以避免unlock不会过早发生。
看到这里我们不禁要问,synchronized与Lock的作用是一样的,那么他们俩到底有什么区别呢?
ReentranLock允许我们尝试获取但最终未获取到锁:
private ReentrantLock lock = new ReentrantLock();public void unTimed(){ boolean captured = lock.tryLock(); try{ System.out.println("tryLock():"+captured); } finally { if(captured){ lock.unlock(); } }}还可以尝试着去获取锁,但是会在指定的时间单位后失败:
public void timed(){ boolean captured = false; try { captured = lock.tryLock(2, TimeUnit.SECONDS); } catch (InterruptedException e) { throw new RuntimeException(e); } try{ System.out.println("tryLock(2, TimeUnit.SECONDS):"+captured); } finally { if(captured){ lock.unlock(); } }}显式的Lock对象在加锁与释放锁方面,相对于内建的synchronized锁来说,赋予了我们更细粒度的控制,我们根据需要来选择具体使用。有一点需要注意的是:Lock对象加锁所造成的阻塞可以被中断,而synchronized不行。
阅读全文
0 0
- Java多线程之synchronized与Lock
- java多线程之synchronized与lock、wait与notify
- Java多线程之synchronized和Lock
- java lock 与 synchronized
- Java多线程编程(四)—浅谈synchronized与lock
- Java多线程编程(四)—浅谈synchronized与lock
- Java多线程编程(四)—浅谈synchronized与lock
- Java多线程编程(四)—浅谈synchronized与lock
- Java多线程 之 访问共享资源synchronized、lock(七)
- 【多线程】多线程同步之synchronized和Lock
- java synchronized与lock区别
- Java synchronized与lock区别
- Java 同步 synchronized与lock
- Java多线程----java 对象锁(synchronized/lock)
- java线程之线程同步与线程通信(Synchronized/Lock)
- java并发之Lock与synchronized的区别
- java并发之Lock与synchronized的区别
- 多线程之lock和synchronized的区别
- 杭电POJ-2161-Primes
- 堡垒机的实现
- pl/sqldeveloper远程连接数据库方法
- linux应用调试技术之GDB和GDBServer
- 设计模式之适配器模式
- Java多线程之synchronized与Lock
- JavaWeb实现文件上传下载功能实例解析
- Python Numpy 学习笔记
- 离散题目四(求交集)
- Java中Synchronized与ReentrantLock的不同以及ReentrantLock的使用
- 排序
- java的hashCode与equals以及HashMap元素确定
- 在线购物系统用况图
- Ubuntu安装微信教程