标签:适用于 void tac inf 技术 结束 子类 tar hide
前言:
前面我们介绍了多线程的控制类ThreadLocal和一些原子类,下面我们来看一下其中两个比较重的关于多线程的控制类和关键字。
一、Lock类:
如下是一张关于Lock接口的接口以及实现类的关系图,接下来就具体来看一下其中的关系:
1、Lock和ReadWriteLock是两大锁的根接口,Lock代表实现类是ReentrantLock(可重入锁),ReadWriteLock(读写锁)的代表实现类是ReentrantReadWriteLock。
Lock 接口支持那些语义不同(重入、公平等)的锁规则,可以在非阻塞式结构的上下文(包括 hand-over-hand 和锁重排算法)中使用这些规则。主要的实现是 ReentrantLock。
ReadWriteLock 接口以类似方式定义了一些读取者可以共享而写入者独占的锁。此包只提供了一个实现,即 ReentrantReadWriteLock,因为它适用于大部分的标准用法上下文。但程序员可以创建自己的、适用于非标准要求的实现。
2、Condition
接口描述了可能会与锁有关联的条件变量。这些变量在用法上与使用 Object.wait
访问的隐式监视器类似,但提供了更强大的功能。需要特别指出的是,单个 Lock 可能与多个 Condition
对象关联。为了避免兼容性问题,Condition 方法的名称与对应的 Object 版本中的不同。
3、可重入锁:
所谓的重入锁,就是线程可以进入他已经拥有锁的的代码中,不可重入锁即线程请求他已经拥有所得代码会阻塞,下面来看一个简单的重入锁案例:
public class ThreadDemo implements Runnable { @Override public void run() { startDo1(); } public synchronized void startDo1(){ System.out.println("可重入锁演示"); startDo2(); } public synchronized void startDo2(){ System.out.println("学不会啊"); } public static void main(String[] args) { Thread thread = new Thread(new ThreadDemo()); thread.start(); } }
上面的代码就是一个简单的重入锁案例,可以看到ThreadDemo勒种有两个同步方法,在startDo1方法中调用了startDo2方法,执行代码后可以正确的运行,也就是线程在进入startDo1方法后拿到了锁,在进入startDo2方法默认也是获取到了锁的,也就是默认第二次获取到了所对象,同时解锁的时候也需要解锁两次,这就是所谓的重入锁。
4、读写锁:
读写锁,即读和写是分开的,我们可以给读加锁,多个线程可以同时读,但是多个线程读的时候是不可以写的,写操作是多个线程不能同时执行写操作的,而且写的时候是不能执行读操作的。
public class ReadWriteDemo{ private Map<String, String> map = new HashMap<String, String>(); private ReentrantReadWriteLock readWrite = new ReentrantReadWriteLock(); private ReentrantReadWriteLock.ReadLock readLock = readWrite.readLock(); private ReentrantReadWriteLock.WriteLock writeLock = readWrite.writeLock(); public String get(String key){ readLock.lock(); try{ System.out.println(Thread.currentThread().getName() + "读操作已加锁,开始读操作……"); Thread.sleep(2000); return map.get(key); }catch(Exception e){ e.printStackTrace(); }finally { System.out.println(Thread.currentThread().getName() +"读操作已解锁,读操作已结束……"); readLock.unlock(); } return null; } public void set(String key, String value){ writeLock.lock(); try{ System.out.println(Thread.currentThread().getName() +"写操作已加锁,开始写操作"); map.put(key,value); Thread.sleep(2000); }catch(Exception e){ e.printStackTrace(); }finally { System.out.println(Thread.currentThread().getName() +"写操作已解锁,写操作已结束……"); writeLock.unlock(); } } }
测试代码:
public class ThreadDemo { public static void main(String[] args) { ReadWriteDemo readWriteDemo = new ReadWriteDemo(); readWriteDemo.set("key","value"); new Thread(() -> { System.out.println(readWriteDemo.get("key")) ; }).start(); } }
测试结果:
main写操作已加锁,开始写操作 main写操作已解锁,写操作已结束…… Thread-0读操作已加锁,开始读操作…… Thread-0读操作已解锁,读操作已结束…… value Process finished with exit code 0
标签:适用于 void tac inf 技术 结束 子类 tar hide
原文地址:https://www.cnblogs.com/zouxiangzhongyan/p/11517866.html