锁是控制多个线程访问共享资源的一种同步机制。
不同锁的应用场景:
悲观锁和乐观锁是两种不同的锁机制:
悲观锁:
乐观锁:
总结:
使用如下:
synchronized
package com.demo1;
import lombok.NonNull;
import lombok.Synchronized;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.concurrent.locks.StampedLock;
public class Lock implements Runnable {
private final ReentrantLock reentrantLock = new ReentrantLock();
private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
private final StampedLock stampedLock = new StampedLock();
@Override
public void run() {
synchronized (Lock.class){
for (int i = 1; i < 100; i++) {
System.out.println(i);
try {
Thread.sleep(10);
} catch (Exception e) {
e.printStackTrace();
}
}
try {
Thread.sleep(3000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void main(String\[\] args) {
//构建线程池
ThreadPoolExecutor pool = new ThreadPoolExecutor(2, 4, 2, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(2), new ThreadFactory() {
@Override
public Thread newThread(@NonNull Runnable r) {
Thread t = new Thread(r);
t.setName("myThread");
return t;
}
}, new ThreadPoolExecutor.AbortPolicy());
Lock l = new Lock();
pool.submit(l);
pool.submit(l);
pool.shutdown();
}
}
ReentrantLock:
@Override
public void run() {
reentrantLock.lock();
for (int i = 1; i < 100; i++) {
System.out.println(i);
try {
Thread.sleep(10);
} catch (Exception e) {
e.printStackTrace();
}
}
try {
Thread.sleep(3000);
} catch (Exception e) {
e.printStackTrace();
}
reentrantLock.unlock();
}
ReadWriteLock:
@Override
public void run() {
readWriteLock.readLock().lock();
for (int i = 1; i < 100; i++) {
System.out.println(i);
try {
Thread.sleep(10);
} catch (Exception e) {
e.printStackTrace();
}
}
try {
Thread.sleep(3000);
} catch (Exception e) {
e.printStackTrace();
}
readWriteLock.readLock().unlock();
}
当使用读锁时,会出现如: 1 1 2 2 3 3这样交替的情况,但是写锁不会出现这种情况
StampedLock:
private final StampedLock lock = new StampedLock();
// 乐观读
public void optimisticRead() {
long stamp = lock.tryOptimisticRead();
// 执行读操作
if(!lock.validate(stamp)){//当出现数据不一致问题时进行升级
// 升级为悲观读锁
stamp = lock.readLock();
try {
// 重做读取操作
} finally {
lock.unlockRead(stamp);
}
}
}
// 悲观写
public void pessimisticWrite() {
long stamp = lock.writeLock();
try {
// 写操作
} finally {
lock.unlockWrite(stamp);
}
}
Semaphore://只允许两个线程同时使用,类似c++的pv操作
private final Semaphore semaphore = new Semaphore(2);
@SneakyThrows
@Override
public void run() {
semaphore.acquire();
System.out.println("执行");
Thread.sleep(3000);
semaphore.release();
}
如果有什么错误,欢迎指正
手机扫一扫
移动阅读更方便
你可能感兴趣的文章