Java并发之线程同步
来源:互联网 发布:粒子群算法工具箱使用 编辑:程序博客网 时间:2024/06/04 18:43
Synchronized关键字
1,用于方法上
2,用于代码块上: 必须通过一个对象引用作为参数。只有一个线程可以访问那个对象的synchronized代码(代码 块或方法)。通常,我们将使用this关键字引用执行该方法的对象。
synchronized (this) {
}
synchronized()保护代码块时,如果使用对象作为参数,而不是this
JVM可以保证只有一个线程可以访问那个对象保护所有的代码块
如: 我们用一个对象来控制name1属性的访问。所以,在任意时刻,只有一个线程能修改该属性。用另一个对象来控制 name2属性的访问。所以,在任意时刻,只有一个线程能修改这个属性。
但是可能有两个线程同时运行,一个修改 name1属性而另一个修改name2属性。
synchronized和下面方法一起使用:
nitifyAll() 通知所有的wait线程返回
nitify() 通知一个wait的线程返回
wait() 会释放对象锁; 被notity后,还需要等待锁,才能返回
使用Lock同步代码块
1,接口Lock, 实现类ReentrantLock
2,它允许以一种更灵活的方式来构建同步块。
3,Lock 接口比synchronized关键字提供更多额外的功能。新功能之一是实现的tryLock()方法。这种方法试图获取锁的控制权并且如果它不能获取该锁,是因为其他线程在使用这个锁,它将返回这个锁。
4,使用synchronized关键字,当线程A试图执行synchronized代码块,如果线程B正在执行它,那么线程A将只能阻塞直到线程B执行完synchronized代码块。使用Lock锁,你可以执行tryLock()方法,这个方法返回一个 Boolean值表示,是否有其他线程锁。代码可以更加灵活。
5,当有多个读和一个写时,Lock接口允许读写操作分离。
6,Lock接口比synchronized关键字提供更好的性能。
ReentrantLock其它方法:
getOwner() 方法来返回线程的名字。
ReentrantLock类保护方法getQueuedThreads(), 返回正在等待执行临界区的线程list。
hasQueuedThreads():此方法返回 Boolean 值表明是否有线程在等待获取此锁
getQueueLength(): 此方法返回等待获取此锁的线程数量
isLocked(): 此方法返回 Boolean 值表明此锁是否为某个线程所拥有
isFair(): 此方法返回 Boolean 值表明锁的 fair 模式是否被激活
读写锁
ReadWriteLock接口,实现类:ReentrantReadWriteLock类
读操作:是通过在 ReadWriteLock接口中声明的readLock()方法获取的。这个锁是实现Lock接口的一个对象,所以我们可以使用lock(), unlock() 和tryLock()方法。
写操作:是通过在ReadWriteLock接口中声明的writeLock()方法获取的。这个锁是实现Lock接 口的一个对象,所以我们可以使用lock(), unlock() 和tryLock()方法。
ReadWriteLock rwlock = new ReentrantReadWriteLock();//读锁rwlock.readLock().lock();//读操作......//释放读锁 rwlock.readLock().unlock();// 写锁rwlock.writeLock().lock();//写操作......//释放写锁 rwlock.writeLock().unlock();
锁的公平性
在ReentrantLock类和 ReentrantReadWriteLock类的构造器中,允许一个名为fair的boolean类型参数,它允许你来控制这些类的行为。
false值: 默认值,启用非公平模式。在这个模式中,当有多个线程正在等待一把锁(ReentrantLock或者 ReentrantReadWriteLock),这个锁必须选择它们中间的一个来获得进入临界区,选择任意一个是没有任何标准的。
true值: 开启公平模式。在这个模式中,当有多个线程正在等待一把锁(ReentrantLock或者ReentrantReadWriteLock),这个锁必须选择它们 中间的一个来获得进入临界区,它将选择等待时间最长的线程。
Condition
Condition接口提供一种机制,阻塞一个线程和唤醒一个被阻塞的线程。
Lock接口中的newCondition()方法来创建。
Lock lock = new ReentrantLock();Condition condition = lock.newCondition();
当一个线程在一个condition上调用await()方法时,它将自动释放锁的控制,并进入Condition变量的等待队列。
当一个线程在一个condition上调用signal()或signallAll()方法,一个或者全部在这个condition上等待的线程将被唤醒,从await方法返回。返回前必须获得锁。
Lock lock = new ReentrantLock(); Condition condition = lock.newCondition(); public void conditionWait() throws InterruptedException { lock.lock(); try { //.... condition.await();//await方法后,线程将释放锁,并且将自己沉睡,等待唤醒 }finally { lock.unlock(); } } public void conditionSignal(){ lock.lock();//上面的线程释放锁后,这里可以获得锁 try { //... condition.signal();//调用Condition的signal方法,唤醒上面线程,但此时锁没有释放,线程1没有真正唤醒 }finally { lock.unlock();//释放锁,线程1将被执行 } }
Condition接口提供不同版本的await()方法,如下:
1,await(long time, TimeUnit unit):这个线程将会一直睡眠直到:
(1)它被中断
(2)其他线程在这个condition上调用singal()或signalAll()方法
(3)指定的时间已经过了
(4)TimeUnit类是一个枚举类型如下的常量:
DAYS,HOURS, MICROSECONDS, MILLISECONDS, MINUTES, NANOSECONDS,SECONDS
2,awaitUninterruptibly():这个线程将不会被中断,一直睡眠直到其他线程调用signal()或signalAll()方法
3,awaitUntil(Date date):这个线程将会一直睡眠直到:
(1)它被中断
(2)其他线程在这个condition上调用singal()或signalAll()方法
(3)指定的日期已经到了
参考资料
并发中文网: http://ifeve.com/
- Java并发之线程同步
- [Java] 线程之并发与同步
- java并发编程-线程同步之synchronized
- 【Java并发学习】之线程的同步
- 多线程并发之线程同步
- Java线程同步于并发
- JAVA并发编程3_线程同步之synchronized关键字
- JAVA并发编程4_线程同步之volatile关键字
- Java多线程与并发(二)之线程同步
- 【5】Java并发编程:线程同步工具之CountDownLatch类
- 《java并发编程实战》:线程同步辅助类之CountDownLatch
- java并发编程之线程同步基础(一)
- java并发编程之线程同步辅助类(一)
- java并发编程之线程同步辅助类(二)
- 【Java并发】(二) 线程同步之Thread.join()、CountDownLatch、CyclicBarrier
- Java并发之线程
- Java并发之线程
- java并发编程之线程同步基础(二)使用锁实现同步
- 关于JAVA语言环境搭建
- Linux上使用Qt Creator进行C/C++开发
- 用C语言实现走迷宫
- log4j日志封装说明—slf4j对于log4j的日志封装-正确获取调用堆栈
- hibernate 配置文件
- Java并发之线程同步
- ImportError: No module named 'sklearn.model_selection'
- JAVA5自动拆箱装箱
- 贾跃亭“老赖”身份登上纽约时报,第二天自封FF电动车的CEO
- ossUploader 阿里云OSS 对象云存储 上传控件
- ros下如何订阅任意话题
- BLEU算法——机器翻译自动评估
- curator实现master选举
- 底部弹出的Popuwindow 用于更换头像