import org.apache.poi.ss.formula.functions.T;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
//lock.lockInterruptibly 调用这个锁,可以通过相应中断 .如果被syn修饰的不能相应中断,线程只能一直阻塞下去
//锁的分类:
//可重入锁 如果一个带锁的方法中调用了另一个带锁的方法,如果不是可重入锁,会造成死锁现象
//可中断锁: syn不能被中断,Lock可以被中断前面演示lockInterruptibly()的用法时已经体现了Lock的可中断性。
//读写锁; 可以提高读的效率
//公平锁和非公平锁 : syn是非公平锁 会导致不是安请求顺序来获取的,可能导致有的线程不能获取到锁
//公平锁: 通过请求顺序来获取所,等待时间最久的线程将会优先获取到锁.Lock和ReadWriteLock都可以设置成公平锁.
public class Test {
private final static Logger logger = LoggerFactory.getLogger(Test.class);
private Lock lock = new ReentrantLock();
private ReadWriteLock writeLock = new ReentrantReadWriteLock();
public static void main(String[] args) {
/* Test test = new Test();
MyThread thread1 = new MyThread(test,"线程1");
MyThread thread2 = new MyThread(test,"线程2");
thread1.start();
thread2.start();*/
Test test = new Test();
new Thread(() -> test.writeLock()).start(); //读写锁 可以提高读的效率.如果一个线程获取了读锁,另一个线程要获取写锁.那么等读锁释放以后才可以获取到写锁. 如果一个线程获取到写锁,另一个线程要获取读锁,也要等写锁释放以后才可以获取
new Thread(() -> test.writeLock()).start();
}
private void writeLock() {
writeLock.readLock().lock();
logger.info(Thread.currentThread().getName() + " 获取到了锁");
try {
long start = System.currentTimeMillis();
while (true) {
logger.info(Thread.currentThread().getName() + " 正在进行读操作");
}
//logger.info(Thread.currentThread().getName() + " 读操作已经结束");
} catch (Exception e) {
e.printStackTrace();
} finally {
logger.info(Thread.currentThread().getName() + " 释放锁");
writeLock.readLock().unlock();
}
}
public synchronized void write() {
long start = System.currentTimeMillis();
while(System.currentTimeMillis() - start < 10) {
logger.info(Thread.currentThread().getName() + " 正在进行读操作");
}
logger.info(Thread.currentThread().getName() + " 读操作已经完毕");
}
public void insert(Thread thread) throws InterruptedException{
lock.lock(); //注意,如果需要正确中断等待锁的线程,必须将获取锁放在外面,然后将InterruptedException抛出
try {
System.out.println(thread.getName()+"得到了锁");
Thread.sleep(4000);
long startTime = System.currentTimeMillis();
for( ; ;) {
if(System.currentTimeMillis() - startTime >= Integer.MAX_VALUE)
break;
//插入数据
}
}
finally {
System.out.println(Thread.currentThread().getName()+"执行finally");
lock.unlock();
System.out.println(thread.getName()+"释放了锁");
}
}
}
class MyThread extends Thread {
private Test test = null;
public MyThread(Test test,String name) {
super(name);
this.test = test;
}
@Override
public void run() {
try {
test.write();
} catch (Exception e) {
System.out.println(Thread.currentThread().getName()+"被中断");
}
}
}
https://www.cnblogs.com/dolphin0520/p/3923167.html