重入锁 ReentrantLock
重入锁示例
lock : 获取锁资源
unLock : 释放锁资源
//重入锁示例
public class TestReentrantLock {
public static ReentrantLock lock=new ReentrantLock(); //重入锁
public static int count = 0 ;
public static void main(String[] args) {
for (int i = 0 ; i < 3 ; i++ ) {
Thread thread = new Thread(
()->{
while (true) {
lock.lock(); //获取锁
count++ ;
if (count > 1000000) {
break;
}
System.out.println(Thread.currentThread().getName() + " ----"+ count);
lock.unlock(); //释放锁
}
}
,"thread--" + i);
thread.start();
}
}
}
//输出
thread--2 ----999996
thread--2 ----999997
thread--2 ----999998
thread--2 ----999999
thread--2 ----1000000
中断响应
lockInterruptibly : 如果线程中断,停止对锁的等待
isHeldByCurrentThread : 判断当前线程是否含有该锁
//中断响应示例
public class TestReentrantLock {
public static ReentrantLock lock1=new ReentrantLock();
public static ReentrantLock lock2=new ReentrantLock();
public static int count=0;
public static void main(String[] args) {
Thread thread=null;
for (int i=1; i < 3; i++) {
thread=new Thread(
() -> {
try {
if (Thread.currentThread().getName().equals("thread--1")) {
lock1.lockInterruptibly(); //获取锁 1
System.out.println(Thread.currentThread().getName() + " lock1 lock ");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
lock2.lockInterruptibly();//获取锁 2
System.out.println(Thread.currentThread().getName() + " lock2 lock ");
} else {
lock2.lockInterruptibly(); //获取锁 2
System.out.println(Thread.currentThread().getName() + " lock2 lock ");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
lock1.lockInterruptibly();//获取锁 1
System.out.println(Thread.currentThread().getName() + " lock1 lock ");
}
count++;
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
System.out.println(Thread.currentThread().getName() + " ----" + count);
if (lock1.isHeldByCurrentThread()) {
lock1.unlock(); //释放锁
System.out.println(Thread.currentThread().getName() + " lock1 unlock ");
}
if (lock2.isHeldByCurrentThread()) {
lock2.unlock(); //释放锁
System.out.println(Thread.currentThread().getName() + " lock2 unlock ");
}
}
}
, "thread--" + i);
thread.start();
}
try {
Thread.sleep(8000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(count);
thread.interrupt(); //中断线程2
//输出
thread--2 lock2 lock
thread--1 lock1 lock
0
thread--2 ----0
thread--2 lock2 unlock
thread--1 lock2 lock
thread--1 ----1
thread--1 lock1 unlock
thread--1 lock2 unlock
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 com.mybatis.datasources.common.concurrent.TestReentrantLock.lambda$main$0(TestReentrantLock.java:40)
at java.lang.Thread.run(Thread.java:745)
限时等待
// 限时等待 在指定时间未获得锁资源后不再等待。
lock.tryLock(5, TimeUnit.SECONDS) // 5秒后不再等待
public static ReentrantLock lock=new ReentrantLock();
// 限时等待 在指定时间未获得锁资源后不再等待。
public static void main(String[] args) {
for (int i=1; i < 3; i++) {
new Thread(
() -> {
try {
if (lock.tryLock(5, TimeUnit.SECONDS)) {
System.out.println(Thread.currentThread().getName() + " get lock success ");
Thread.sleep(3);
lock.unlock();
} else {
System.out.println(Thread.currentThread().getName() + " get lock fail ");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
, "thread --" + i).start();
}
}
//输出
thread --2 get lock success
thread --1 get lock success
公平锁
//公平锁,获取cpu执行权的几率相同
public static ReentrantLock fairLock=new ReentrantLock(true);
public static void main(String[] args) {
for(int i = 1 ; i< 3 ; i++) {
Thread thread=new Thread(
() -> {
while (true) {
fairLock.lock();
System.out.println(Thread.currentThread().getName() + " is getLocked");
fairLock.unlock();
}
}
, "thread -- " + i);
thread.start();
}
}
//输出
thread -- 2 is getLocked
thread -- 1 is getLocked
thread -- 2 is getLocked
thread -- 1 is getLocked
thread -- 2 is getLocked
thread -- 1 is getLocked
条件condition
ReentrantLock配合使用
//await :挂起线程等待,释放锁资源
//signal : 唤醒线程
public static ReentrantLock lock=new ReentrantLock();
public static Condition condition = lock.newCondition();
public static void main(String[] args) {
Thread thread=new Thread(
()->{
lock.lock();
try {
System.out.println(Thread.currentThread().getName() +" is wait ");
condition.await(); //释放锁资源
} catch (InterruptedException e) {
}
System.out.println(Thread.currentThread().getName() +" is notify and end ");
lock.unlock();
}
," thread -- 1");
thread.start();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
lock.lock();
condition.signal(); //叫醒等待线程。
lock.unlock();
}
//输出
thread -- 1 is wait
thread -- 1 is notify and end
Semaphore信号量
//信号量
//可以控制同时执行的线程数量
//semaphore.acquire(); 计数
//semaphore.release(); 释放线程
public static Semaphore semaphore=new Semaphore(5);
public static void main(String[] args) {
ExecutorService executorService=Executors.newFixedThreadPool(20);
for(int i = 0 ; i <20 ; i ++) {
executorService.submit(
()->{
try {
semaphore.acquire();
Thread.sleep(2000);
System.out.println(Thread.currentThread().getId() +" is end");
semaphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
);
}
executorService.shutdown();
}
}
//输出 每次都是五个线程执行
13 is end
11 is end
14 is end
15 is end
12 is end
20 is end
16 is end
17 is end
18 is end
19 is end
22 is end
25 is end
21 is end
24 is end
23 is end
29 is end
26 is end
30 is end
28 is end
27 is end
ReentantReadWriteLock 读写锁
//读写锁
//读写:会互相阻塞
//写写:会互相阻塞
//读读:不会阻塞
public static Lock lock = new ReentrantLock();
public static ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();
public static Lock readLock = reentrantReadWriteLock.readLock(); //读锁
public static Lock writeLock = reentrantReadWriteLock.writeLock(); //写锁
public static int count ;
public static int read(Lock lock) {
lock.lock();
try {
Thread.sleep(1000);
System.out.println(System.currentTimeMillis() + " read " + count);
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
lock.unlock();
}
return count ;
}
public static void write(Lock lock,int count) {
lock.lock();
try {
Thread.sleep(500);
System.out.println(System.currentTimeMillis() + " write " + count);
TestReadWriteLock.count = count;
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
lock.unlock();
}
}
public static void main(String[] args) {
for(int i = 0 ; i < 20 ;i ++) {
new Thread(
()-> read(lock) //20个线程进行读的操作
//()-> read(readLock)
).start();
}
for (int i = 0; i< 2; i ++) {
new Thread( //2个线程进行写的操作
()-> write(lock,new Random().nextInt(10))
//()-> write(writeLock,new Random().nextInt(10))
).start();
}
}
//输出1 重入锁
// 1495871944846 read 0
// 1495871945847 read 0
// 1495871946847 read 0
// 1495871947847 read 0
// 1495871948848 read 0
// 1495871949848 read 0
// 1495871950848 read 0
// 1495871951848 read 0
// 1495871952848 read 0
// 1495871953848 read 0
// 1495871954848 read 0
// 1495871955848 read 0
// 1495871956848 read 0
// 1495871957848 read 0
// 1495871958848 read 0
// 1495871959848 read 0
// 1495871960848 read 0
// 1495871961848 read 0
// 1495871962848 read 0
// 1495871963849 read 0
// 1495871964349 write 0
// 1495871964849 write 9
//输出2 读写锁
// 1495871787331 read 0
// 1495871787332 read 0
// 1495871787333 read 0
// 1495871787336 read 0
// 1495871787342 read 0
// 1495871787345 read 0
// 1495871787352 read 0
// 1495871787352 read 0
// 1495871787352 read 0
// 1495871787352 read 0
// 1495871787352 read 0
// 1495871787854 write 6
// 1495871788855 read 6
// 1495871788855 read 6
// 1495871788855 read 6
// 1495871788855 read 6
// 1495871788855 read 6
// 1495871788855 read 6
// 1495871789356 write 3
// 1495871790356 read 3
// 1495871790356 read 3
// 1495871790356 read 3
CountDownLatch 倒计时器
//倒计时器
//控制多线程等待,指定数量线程完成后执行主线程
countDownLatch.await(); //等待计数
public static CountDownLatch countDownLatch=new CountDownLatch(10);
public static void main(String[] args) {
ExecutorService executorService=Executors.newFixedThreadPool(10);
for(int i = 0 ; i < 10 ; i++ ) {
executorService.submit(
()->{
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
System.out.println(" thread is end ");
countDownLatch.countDown();
}
);
}
try {
countDownLatch.await(); //等待计数器完成后执行
} catch (InterruptedException e) {
}
System.out.println(" countDownLatch is end ");
executorService.shutdown();
}
//输出
//thread is end
//thread is end
//thread is end
//thread is end
//thread is end
//thread is end
//thread is end
//thread is end
//thread is end
//thread is end
//countDownLatch is end
循环栅栏CyclicBarrier
//循环栅栏
//每达到指定的N个线程后执行栅栏中的任务
cyclicBarrier.await(); //计数等待
public static boolean flag = false ;
public static void main(String[] args) {
CyclicBarrier cyclicBarrier = new CyclicBarrier(10,
()->{
if (flag) {
System.out.println( "thread is done");
}else{
System.out.println(" thread is coming");
flag = true;
}
}
);
for(int i = 0 ; i < 10 ; i ++) {
new Thread(
()->{
try {
cyclicBarrier.await(); //计数等待
//do work
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName() + " is running");
//cyclicBarrier.await(); //计数等待
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
," thread -- " + i).start();
}
//输出1 :无任务注释
//thread is coming
//thread -- 0 is running
//thread -- 9 is running
//thread -- 1 is running
//thread -- 2 is running
//thread -- 8 is running
//thread -- 4 is running
//thread -- 5 is running
//thread -- 3 is running
//thread -- 7 is running
//thread -- 6 is running
//thread is done
//输出2 注释第一个 cyclicBarrier.await();
//thread -- 1 is running
//thread -- 3 is running
//thread -- 7 is running
//thread -- 5 is running
//thread -- 9 is running
//thread -- 0 is running
//thread -- 8 is running
//thread -- 4 is running
//thread -- 2 is running
//thread -- 6 is running
//thread is coming
//输出3 注释第二个 cyclicBarrier.await();
//thread is coming
//thread -- 3 is running
//thread -- 7 is running
//thread -- 5 is running
//thread -- 1 is running
//thread -- 9 is running
//thread -- 2 is running
//thread -- 6 is running
//thread -- 8 is running
//thread -- 0 is running
//thread -- 4 is running
}
线程阻塞
// LockSupport
// LockSupport.park(); //阻塞线程 不会释放锁资源,会立刻中断响应
// LockSupport.unpark(thread1);
public static Object object = new Object();
public static void main(String[] args) {
Thread thread1 = new Thread(
()->{
synchronized (object) {
System.out.println(Thread.currentThread().getName() + " is running");
LockSupport.park(); //阻塞线程 不会释放锁资源
System.out.println(Thread.currentThread().getName() + " is end");
}
}
,"thread -- 1");
Thread thread2 = new Thread(
()->{
synchronized (object) {
System.out.println(Thread.currentThread().getName() + " is running");
LockSupport.park(); //阻塞线程 不会释放锁资源
System.out.println(Thread.currentThread().getName() + " is end");
}
}
," thread -- 2");
thread1.start();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
thread2.start();
LockSupport.unpark(thread1);
LockSupport.unpark(thread2);
}
//输出
//thread -- 1 is running
//thread -- 1 is end
//thread -- 2 is running
//thread -- 2 is end
本文深入探讨了Java并发编程的关键概念和技术,包括ReentrantLock的使用方法及其特性,如重入锁、公平锁、中断响应、限时等待等。此外,还介绍了Condition条件变量、Semaphore信号量、CountDownLatch倒计时器和CyclicBarrier循环栅栏的作用及应用场景,并对比了读写锁的工作原理。

238

被折叠的 条评论
为什么被折叠?



