synchronized的功能拓展:重入锁(读书笔记)
public class ReenterLock implements Runnable {
public static ReentrantLock lock = new ReentrantLock();
public static int i = 0; /**
* When an object implementing interface <code>Runnable</code> is used
* to create a thread, starting the thread causes the object's
* <code>run</code> method to be called in that separately executing
* thread.
* <p>
* The general contract of the method <code>run</code> is that it may
* take any action whatsoever.
*
* @see Thread#run()
*/
@Override
public void run() {
for (int j = 0; j < 10000000; j++) {
lock.lock();//加锁
try {
i++;
} finally {
lock.unlock();//释放锁
}
}
} public static void main(String[] args) throws InterruptedException {
ReenterLock t1 = new ReenterLock();//线程实例
Thread th1 = new Thread(t1);
Thread th2 = new Thread(t1);
th1.start();
th2.start();
th1.join();
th2.join();
System.out.println("i = " + i);
}
}
- 中断响应 与synchronized相比,如果一个线程在等待锁,那么结果只要两种情况,1 获得这把锁执行, 2 他保持等待状态,而使用重入锁,则提供了另外一种可能性,那就是线程可以被中断,也就是在等待过程中,程序可以根据需要取消对锁的请求.
public class IntLock implements Runnable {
public static ReentrantLock lock1 = new ReentrantLock();
public static ReentrantLock lock2 = new ReentrantLock();
int lock; public IntLock(int lock) {
this.lock = lock;
} /**
* When an object implementing interface <code>Runnable</code> is used
* to create a thread, starting the thread causes the object's
* <code>run</code> method to be called in that separately executing
* thread.
* <p>
* The general contract of the method <code>run</code> is that it may
* take any action whatsoever.
*
* @see Thread#run()
*/
@Override
public void run() {
try {
if (lock == 1) {
lock1.lockInterruptibly();//锁1 这是一个可以对中断进行想要的锁申请动作!
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
lock2.lockInterruptibly();//锁2 加锁
} else {
lock2.lockInterruptibly();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
lock1.lockInterruptibly();//锁1 加锁
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
if (lock1.isHeldByCurrentThread()) { //判断持有自己锁的线程是否是当前线程
lock1.unlock();
}
if (lock2.isHeldByCurrentThread()) {
lock2.unlock();
}
System.out.println(Thread.currentThread().getId() + ":线程退出");
}
} public static void main(String[] args) throws InterruptedException {
IntLock r1 = new IntLock(1);//线程实例 1
IntLock r2 = new IntLock(2);//线程实例 2
Thread t1 = new Thread(r1);//线程1
Thread t2 = new Thread(r2);//线程2
t1.start();
t2.start();
Thread.sleep(1000);//Main线程 休眠1s t2.interrupt();//中断其中一个线程 }
}
- 锁申请等待限时 除了等待通知之外,要避免死锁还有另外一种方法,那就是限时等待, 就是规定一个时间,超出时间没有拿到锁 就退出
public class TimeLock implements Runnable {
public static ReentrantLock lock = new ReentrantLock(); /**
* When an object implementing interface <code>Runnable</code> is used
* to create a thread, starting the thread causes the object's
* <code>run</code> method to be called in that separately executing
* thread.
* <p>
* The general contract of the method <code>run</code> is that it may
* take any action whatsoever.
*
* @see Thread#run()
*/
@Override
public void run() {
try {
if (lock.tryLock(5, TimeUnit.SECONDS)) {//试图获取锁,等待5秒 如果超时那就false
Thread.sleep(6000);
} else {
System.out.println("get lock failed");
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
if (lock.isHeldByCurrentThread()) {
lock.unlock();
}
}
} public static void main(String[] args) {
TimeLock r1 = new TimeLock();
Thread t1 = new Thread(r1);
Thread t2 = new Thread(r1);
t1.start();
t2.start();
}
}
public class TryLock implements Runnable {
public static ReentrantLock lock1 = new ReentrantLock();
public static ReentrantLock lock2 = new ReentrantLock();
int lock; public TryLock(int lock) {
this.lock = lock;
} /**
* When an object implementing interface <code>Runnable</code> is used
* to create a thread, starting the thread causes the object's
* <code>run</code> method to be called in that separately executing
* thread.
* <p>
* The general contract of the method <code>run</code> is that it may
* take any action whatsoever.
*
* @see Thread#run()
*/
@Override
public void run() {
if (lock == 1) {
while (true) {
if (lock1.tryLock()) {
try {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (lock2.tryLock()) {
try {
System.out.println(Thread.currentThread().getId() + ":My Job done");
return;
} finally {
lock2.unlock();
}
}
} finally {
lock1.unlock();
}
}
}
} else {
while (true) {
if (lock2.tryLock()) {
try {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (lock1.tryLock()) {
try {
System.out.println(Thread.currentThread().getId() + ":My Job done");
return;
} finally {
lock1.unlock();
}
}
} finally {
lock2.unlock();
}
}
}
}
} public static void main(String[] args) {
TryLock r1 = new TryLock(1);
TryLock r2 = new TryLock(2);
Thread t1 = new Thread(r1);
Thread t2 = new Thread(r2);
t1.start();
t2.start();
}
}
- 公平锁 在大多情况下.锁的申请都是非公平的.两个线程同时申请锁a,谁先获得锁a呢 这是不一定的,系统只是会从这个锁的等待队列中随机挑选一个.而公平的锁,则不是这样的,他会按照时间的先后顺序,保证先到先得,后到后的,公平锁的一大特点就是,不会产生饥饿现象,只要你排队,最终还是可以得到资源的, 如果我们使用synchronized关键字进行锁控制,那么产生的锁就是非公平的,而重入锁循序我们对其公平性进行设置,下面是他的构造器
sync = fair ? new FairSync() : new NonfairSync();
}
synchronized的功能拓展:重入锁(读书笔记)的更多相关文章
- 浅谈Java中的锁:Synchronized、重入锁、读写锁
Java开发必须要掌握的知识点就包括如何使用锁在多线程的环境下控制对资源的访问限制 ◆ Synchronized ◆ 首先我们来看一段简单的代码: 12345678910111213141516171 ...
- synchronized 是可重入锁吗?为什么?
什么是可重入锁? 关于什么是可重入锁,我们先来看一段维基百科的定义. 若一个程序或子程序可以“在任意时刻被中断然后操作系统调度执行另外一段代码,这段代码又调用了该子程序不会出错”,则称其为可重入(re ...
- java 可重入锁ReentrantLock的介绍
一个小例子帮助理解(我们常用的synchronized也是可重入锁) 话说从前有一个村子,在这个村子中有一口水井,家家户户都需要到这口井里打水喝.由于井水有限,大家只能依次打水.为了实现家家有水喝,户 ...
- java高并发系列 - 第12天JUC:ReentrantLock重入锁
java高并发系列 - 第12天JUC:ReentrantLock重入锁 本篇文章开始将juc中常用的一些类,估计会有十来篇. synchronized的局限性 synchronized是java内置 ...
- JUC 一 ReentrantLock 可重入锁
java.util.concurrent.locks ReentrantLock即可重入锁,实现了Lock和Serializable接口 ReentrantLock和synchronized都是可重入 ...
- 可重入锁 & 自旋锁 & Java里的AtomicReference和CAS操作 & Linux mutex不可重入
之前还是写过蛮多的关于锁的文章的: http://www.cnblogs.com/charlesblc/p/5994162.html <[转载]Java中的锁机制 synchronized &a ...
- Java并发编程-可重入锁
可重入锁,也叫做递归锁,指的是同一线程 外层函数获得锁之后 ,内层递归函数仍可以获取该锁而不受影响.在JAVA环境下 ReentrantLock 和synchronized 都是 可重入锁. publ ...
- 可重入锁(good)
可重入锁,也叫做递归锁,是指在一个线程中可以多次获取同一把锁,比如:一个线程在执行一个带锁的方法,该方法中又调用了另一个需要相同锁的方法,则该线程可以直接执行调用的方法[即可重入],而无需重新获得锁: ...
- Java可重入锁如何避免死锁
本文由https://bbs.csdn.net/topics/390939500和https://zhidao.baidu.com/question/1946051090515119908.html启 ...
随机推荐
- [01]关于TDD、BDD和DDD的一些看法
在实际的项目中,我们可能随时面对各种不同的需求,它的各个方面的要素决定了我们所采用的开发模式. 比如,它的复杂度如何?所有的需求是否足够清晰?开发人员对相关的业务是否足够了解?项目的工期是否合理?种种 ...
- 转:ListView中getView的工作原理
ListView中getView的工作原理: [1]ListView asks adapter “give me a view” (getView) for each item of the list ...
- 汕头市队赛 SRM14 T1 计算几何瞎暴力
计算几何瞎暴力 (easy.pas/c/cpp) 128MB 1s 在平面上,给定起点和终点,有一面墙(看作线段)不能穿过,问从起点走到终点的最短路程. 输入格式 输入一行,包含8个用空格分隔的整数x ...
- apache快速配置简易网站
网站源文件目录 F:\01.prj\site\static_html F:\01.prj\site\static_html 打开apache_http.conf 1 .修改网站目录 错误1 Alias ...
- Linux Context , Interrupts 和 Context Switching 说明【转】
转自:http://blog.csdn.net/tianlesoftware/article/details/6461207 一. 进程Context 定义 当一个进程在执行时, CPU的所有寄存器中 ...
- C++文件(夹)选择对话框
由于各种应用,我们需要调用系统的打开文件对话框或者打开文件夹对话框,或两者兼有.今遇到这个情况已经解决,特写下这篇博文. 1.打开文件对话框常用的方法是使用系统的CFileDialog.这里介绍另外一 ...
- Android应用开发之使用Socket进行大文件断点上传续传
http://www.linuxidc.com/Linux/2012-03/55567.htm http://blog.csdn.net/shimiso/article/details/8529633 ...
- AC日记——Little Elephant and Array codeforces 221d
221D - Little Elephant and Array 思路: 莫队: 代码: #include <cmath> #include <cstdio> #include ...
- AC日记——奶牛集会 洛谷 P2345
奶牛集会 思路: 把奶牛按照v排序: 然后,每次都把奶牛放入一个集合s: 因为奶牛已经排序: 所以,每次第i次放入奶牛起作用的v就是vi: 每次ans+=(xi*sum-sumxl)*vi+(sumx ...
- 关于ScrollView嵌套RecyclerView出现item显示不全的问题
最近使用ScrollView时,发现里面嵌套Listview显示不全,试过重写Listview的onMeasure(),并没有起作用.然后将ListView换成RecyclerView后,高度还是显示 ...