Lock之ReentrantLock
Posted yangyongjie
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Lock之ReentrantLock相关的知识,希望对你有一定的参考价值。
Conditon中的await()对应Object的wait(),Condition中的signal()对应Object的notify(),Condition中的signalAll()对应Object的notifyAll()
两个线程交替执行例子(同理生产者消费者也是这样交替执行):
package com.yang.spbo.other.lock; import java.util.concurrent.LinkedBlockingDeque; import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; /** * A,B两个线程交替执行 * 〈功能详细描述〉 * * @author 17090889 * @see [相关类/方法](可选) * @since [产品/模块版本] (可选) */ public class ConditionService private ReentrantLock lock = new ReentrantLock(); /** * 两个线程所以创建两个condition */ private Condition A = lock.newCondition(); private Condition B = lock.newCondition(); private int number = 1; private boolean flag = false; private void executeA() while (number < 100) try lock.lock(); if (!flag) System.out.println("A等待"); A.await(); System.out.println("A " + number); number++; flag = false; System.out.println("B唤醒"); B.signal(); catch (InterruptedException e) e.printStackTrace(); finally lock.unlock(); private void executeB() while (number < 100) try lock.lock(); if (flag) System.out.println("B等待"); B.await(); System.out.println("B " + number); number++; flag = true; System.out.println("A唤醒"); A.signal(); catch (InterruptedException e) e.printStackTrace(); finally lock.unlock(); public static void main(String[] args) final ConditionService cs = new ConditionService(); ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 5, 1, TimeUnit.MINUTES, new LinkedBlockingDeque<Runnable>(1000), new MyThreadFactory("conditionService")); executor.execute(new Runnable() @Override public void run() System.out.println(Thread.currentThread().getName()); cs.executeA(); ); executor.execute(new Runnable() @Override public void run() System.out.println(Thread.currentThread().getName()); cs.executeB(); ); static class MyThreadFactory implements ThreadFactory /** * 线程名字前缀 */ private String namePrefix; private AtomicInteger id = new AtomicInteger(1); public MyThreadFactory(String namePrefix) this.namePrefix = namePrefix; @Override public Thread newThread(Runnable r) String threadName = namePrefix + "-worker-" + id.getAndIncrement(); Thread thread; thread = new Thread(r, threadName); return thread;
运行结果:
conditionService-worker-1
A等待
conditionService-worker-2
B 1
A唤醒
B等待
A 2
B唤醒
A等待
B 3
A唤醒
B等待
A 4
B唤醒
A等待
B 5
A唤醒
B等待
A 6
ReentrantLock实现死锁:
/** * ReentrantLock实现死锁 * 〈功能详细描述〉 * * @author 17090889 * @see [相关类/方法](可选) * @since [产品/模块版本] (可选) */ public class DeadLockTest private static ReentrantLock lock1 = new ReentrantLock(); private static ReentrantLock lock2 = new ReentrantLock(); public static void main(String[] args) new Thread(new Runnable() @Override public void run() lock1.lock(); try Thread.sleep(1000); lock2.lock(); catch (InterruptedException e) e.printStackTrace(); finally lock1.unlock(); ).start(); new Thread(new Runnable() @Override public void run() lock2.lock(); try Thread.sleep(1000); lock1.lock(); catch (InterruptedException e) e.printStackTrace(); finally lock2.unlock(); ).start();
分析过程:
1.
c:\Program Files\Java\jdk1.7.0_79\bin>jps
7996 Main
3960 Jps
8396 Launcher
5568 Launcher
1204
8212 Bootstrap
396 ProfilerServer
7996 Main
3960 Jps
8396 Launcher
5568 Launcher
1204
8212 Bootstrap
396 ProfilerServer
8036 DeadLockTest
2.c:\Program Files\Java\jdk1.7.0_79\bin>jstack 8036
Found one Java-level deadlock:
=============================
"Thread-1":
waiting for ownable synchronizer 0x00000007d5e6f5c0, (a java.util.concurrent.l
ocks.ReentrantLock$NonfairSync),
which is held by "Thread-0"
"Thread-0":
waiting for ownable synchronizer 0x00000007d5e6f5f0, (a java.util.concurrent.l
ocks.ReentrantLock$NonfairSync),
which is held by "Thread-1"
Java stack information for the threads listed above:
===================================================
"Thread-1":
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000007d5e6f5c0> (a java.util.concurrent.lock
s.ReentrantLock$NonfairSync)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInt
errupt(AbstractQueuedSynchronizer.java:834)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(A
bstractQueuedSynchronizer.java:867)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(Abstrac
tQueuedSynchronizer.java:1197)
at java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLo
ck.java:214)
at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:290)
at deadLock.DeadLockTest$2.run(DeadLockTest.java:38)
at java.lang.Thread.run(Thread.java:745)
"Thread-0":
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000007d5e6f5f0> (a java.util.concurrent.lock
s.ReentrantLock$NonfairSync)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInt
errupt(AbstractQueuedSynchronizer.java:834)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(A
bstractQueuedSynchronizer.java:867)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(Abstrac
tQueuedSynchronizer.java:1197)
=============================
"Thread-1":
waiting for ownable synchronizer 0x00000007d5e6f5c0, (a java.util.concurrent.l
ocks.ReentrantLock$NonfairSync),
which is held by "Thread-0"
"Thread-0":
waiting for ownable synchronizer 0x00000007d5e6f5f0, (a java.util.concurrent.l
ocks.ReentrantLock$NonfairSync),
which is held by "Thread-1"
Java stack information for the threads listed above:
===================================================
"Thread-1":
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000007d5e6f5c0> (a java.util.concurrent.lock
s.ReentrantLock$NonfairSync)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInt
errupt(AbstractQueuedSynchronizer.java:834)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(A
bstractQueuedSynchronizer.java:867)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(Abstrac
tQueuedSynchronizer.java:1197)
at java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLo
ck.java:214)
at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:290)
at deadLock.DeadLockTest$2.run(DeadLockTest.java:38)
at java.lang.Thread.run(Thread.java:745)
"Thread-0":
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000007d5e6f5f0> (a java.util.concurrent.lock
s.ReentrantLock$NonfairSync)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInt
errupt(AbstractQueuedSynchronizer.java:834)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(A
bstractQueuedSynchronizer.java:867)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(Abstrac
tQueuedSynchronizer.java:1197)
at java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLo
ck.java:214)
at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:290)
at deadLock.DeadLockTest$1.run(DeadLockTest.java:24)
at java.lang.Thread.run(Thread.java:745)
Found 1 deadlock.
synchronized实现死锁:
/** * synchronized实现死锁 * 〈功能详细描述〉 * * @author 17090889 * @see [相关类/方法](可选) * @since [产品/模块版本] (可选) */ public class DeadLockTest2 private static Object obj1 = new Object(); private static Object obj2 = new Object(); public static void main(String[] args) new Thread(new Runnable() @Override public void run() synchronized (obj1) System.out.println("thead1 get lock1"); try Thread.sleep(1000); catch (InterruptedException e) e.printStackTrace(); synchronized (obj2) System.out.println("thead1 get lock2"); System.out.println("thread1 end"); , "thead1").start(); new Thread(new Runnable() @Override public void run() synchronized (obj2) System.out.println("thead2 get lock2"); try Thread.sleep(1000); catch (InterruptedException e) e.printStackTrace(); synchronized (obj1) System.out.println("thead2 get lock1"); System.out.println("thread2 end"); , "thead2").start();
Found one Java-level deadlock:
=============================
"thead2":
waiting to lock monitor 0x000000000b15a7c8 (object 0x00000007d5e6f290, a java.
lang.Object),
which is held by "thead1"
"thead1":
waiting to lock monitor 0x000000000b1593d8 (object 0x00000007d5e6f2a0, a java.
lang.Object),
which is held by "thead2"
Java stack information for the threads listed above:
===================================================
"thead2":
at deadLock.DeadLockTest2$2.run(DeadLockTest2.java:44)
- waiting to lock <0x00000007d5e6f290> (a java.lang.Object)
- locked <0x00000007d5e6f2a0> (a java.lang.Object)
at java.lang.Thread.run(Thread.java:745)
"thead1":
at deadLock.DeadLockTest2$1.run(DeadLockTest2.java:27)
- waiting to lock <0x00000007d5e6f2a0> (a java.lang.Object)
- locked <0x00000007d5e6f290> (a java.lang.Object)
at java.lang.Thread.run(Thread.java:745)
=============================
"thead2":
waiting to lock monitor 0x000000000b15a7c8 (object 0x00000007d5e6f290, a java.
lang.Object),
which is held by "thead1"
"thead1":
waiting to lock monitor 0x000000000b1593d8 (object 0x00000007d5e6f2a0, a java.
lang.Object),
which is held by "thead2"
Java stack information for the threads listed above:
===================================================
"thead2":
at deadLock.DeadLockTest2$2.run(DeadLockTest2.java:44)
- waiting to lock <0x00000007d5e6f290> (a java.lang.Object)
- locked <0x00000007d5e6f2a0> (a java.lang.Object)
at java.lang.Thread.run(Thread.java:745)
"thead1":
at deadLock.DeadLockTest2$1.run(DeadLockTest2.java:27)
- waiting to lock <0x00000007d5e6f2a0> (a java.lang.Object)
- locked <0x00000007d5e6f290> (a java.lang.Object)
at java.lang.Thread.run(Thread.java:745)
Found 1 deadlock.
以上是关于Lock之ReentrantLock的主要内容,如果未能解决你的问题,请参考以下文章
Java多线程之ReentrantLock与Condition
Java开发之高并发必备篇——Lock和ReentrantLock
Java开发之高并发必备篇——Lock和ReentrantLock