ReentrantLock
- 可重入
来看个demo:
package someTest;
import java.util.concurrent.locks.ReentrantLock;
public class ReentrantLockDemo implements Runnable{
public static ReentrantLock lock=new ReentrantLock();
public static int i=0;
@Override
public void run() {
for(int j=0;j<100000;j++) {
lock.lock();
try {
i++;
}finally {
lock.unlock();
}
}
}
public static void main(String[] args) throws InterruptedException {
ReentrantLockDemo demo=new ReentrantLockDemo();
Thread t1=new Thread(demo);
Thread t2=new Thread(demo);
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println(i);
}
}
输出结果:
200000
需要注意的问题:
一个线程执行了几次lock.lock();代码,对应的,在finally块当中就要执行几次lock.unlock();代码,否则别的线程就进不来了
- 可中断
来看个demo,这可是个面试题
package someTest;
import java.util.concurrent.locks.ReentrantLock;
public class ReentrantLockInterruptDemo implements Runnable{
public static ReentrantLock lock1=new ReentrantLock();
public static ReentrantLock lock2=new ReentrantLock();
int lock;
public ReentrantLockInterruptDemo(int lock) {
this.lock=lock;
}
@Override
public void run() {
try {
if(lock==1) {
lock1.lockInterruptibly();
try {
Thread.sleep(500);
}catch (InterruptedException e) {
e.printStackTrace();
}
lock2.lockInterruptibly();
}else {
lock2.lockInterruptibly();
try {
Thread.sleep(500);
}catch (InterruptedException e) {
e.printStackTrace();
}
lock1.lockInterruptibly();
}
}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 {
ReentrantLockInterruptDemo r1=new ReentrantLockInterruptDemo(1);
ReentrantLockInterruptDemo r2=new ReentrantLockInterruptDemo(2);
Thread t1=new Thread(r1);
Thread t2=new Thread(r2);
t1.start();
t2.start();Thread.sleep(1000);
DeadlockChecker.check();
}
}
辅助程序:DeadlockChecker.java,一个守护线程,看是否有死锁线程
package someTest;
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
/** 检查死锁 */
public class DeadlockChecker {
private final static ThreadMXBean mbean = ManagementFactory.getThreadMXBean();
final static Runnable deadLockChecker = new Runnable() {
@Override
public void run() {
while(true){
long[] deadLockedThreadIds = mbean.findDeadlockedThreads();
if(deadLockedThreadIds != null){
ThreadInfo[] threadInfos = mbean.getThreadInfo(deadLockedThreadIds);
for(Thread t : Thread.getAllStackTraces().keySet()){
for(ThreadInfo ti : threadInfos){
if(ti.getThreadId() == t.getId()){
t.interrupt();
}
}
}
}
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
public static void check() {
Thread t = new Thread(deadLockChecker);
t.setDaemon(true);
t.start();
}
}
程序输出:
java.lang.InterruptedException
10:线程退出
11:线程退出
at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireInterruptibly(AbstractQueuedSynchronizer.java:898)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireInterruptibly(AbstractQueuedSynchronizer.java:1222)
at java.util.concurrent.locks.ReentrantLock.lockInterruptibly(ReentrantLock.java:335)
at someTest.ReentrantLockInterruptDemo.run(ReentrantLockInterruptDemo.java:22)
at java.lang.Thread.run(Thread.java:748)
java.lang.InterruptedException
at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireInterruptibly(AbstractQueuedSynchronizer.java:898)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireInterruptibly(AbstractQueuedSynchronizer.java:1222)
at java.util.concurrent.locks.ReentrantLock.lockInterruptibly(ReentrantLock.java:335)
at someTest.ReentrantLockInterruptDemo.run(ReentrantLockInterruptDemo.java:30)
at java.lang.Thread.run(Thread.java:748)
- 可定时
来看个demo:
package someTest;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
public class TimedLock implements Runnable{
public static ReentrantLock lock=new ReentrantLock();
@Override
public void run() {
try {
if(lock.tryLock(5, TimeUnit.SECONDS)) {
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) {
TimedLock ins=new TimedLock();
Thread t1=new Thread(ins);
Thread t2=new Thread(ins);
t1.start();
t2.start();
}
}
输出结果:
get lock failed
- 公平锁
这个看看就好,一般公平锁的性能不是很好,先到先得,需要处理一个排队的问题
public ReentrantLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
}
补充
- jps:查看当前运行的java线程
- jstack:查看线程栈上的信息
网友评论