十一多线程控制类

Posted zouxiangzhongyan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了十一多线程控制类相关的知识,希望对你有一定的参考价值。

前言:

  前面我们介绍了多线程的控制类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();
    
View Code

    上面的代码就是一个简单的重入锁案例,可以看到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();
        
    
View Code

    测试代码:

技术图片
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();
    
View Code

    测试结果:

技术图片
main写操作已加锁,开始写操作
main写操作已解锁,写操作已结束……
Thread-0读操作已加锁,开始读操作……
Thread-0读操作已解锁,读操作已结束……
value

Process finished with exit code 0
View Code

 

以上是关于十一多线程控制类的主要内容,如果未能解决你的问题,请参考以下文章

实验十七 线程同步控制

学习JAVA第十九天

十信号量控制Semaphore

Java 多线程基础

Java并发工具类控制并发线程数的Semaphore

并发工具类控制并发线程的数量 Semphore