Concurrent包之lock

2022-10-27 16:35:30 浏览数 (1)

Lock是JDK1.5提供的一个表示锁的新接口

提供了用于加锁的方法lock()以及解锁的方法unLock();

相对传统的synchronized而言,Lock提供有公平和非公平策略,所以Lock的应用更加灵活。

例如一个整数在多线程下的自增

代码语言:javascript复制
package com.jmy.concurrent;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class LockDemo {
    static int i;
    public static void main(String[] args) {

        Lock lock = new ReentrantLock();
        new Thread(new AddDemo(lock)).start();
        new Thread(new AddDemo(lock)).start();

        try {
            Thread.sleep();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(i);
    }

}

class AddDemo implements Runnable {

    private Lock lock;

    public AddDemo(Lock lock) {
        this.lock = lock;
    }

    @Override
    public void run() {

        for (int i = ; i < ; i  ) {
            lock.lock();
            LockDemo.i  ;
            lock.unlock();
        }

    }
}
代码语言:javascript复制
公平和非公平策略

公平策略:在被抢占的资源前加一个工作队列(阻塞队列),线程 抢占的为工作队列的入队顺序,相对公平。

非公平策略:加锁时不考虑队列,线程直接抢占资源,效率较高。 synchronized是非公评策略

Lock默认是非公平策略,可以手动设置为公平策略(构造方法提供Boolean参数)

代码语言:javascript复制
读写锁

读写锁分为读锁和写锁

读锁:允许多个线程读取,但是不允许线程写入

写锁:允许一个线程写入,但是不允许线程读取

代码语言:javascript复制
CountDownLatch

CountDownLatch被称为闭锁或者线程递减锁 用于线程计数,当计数技术后才会执行其他线程。 例如一场面试要等面试官到场才可以开始


代码语言:javascript复制
package com.jmy.concurrent;

import java.util.concurrent.CountDownLatch;

public class CountDownLatchDemo {
    public static void main(String[] args) throws InterruptedException {
        CountDownLatch countDownLatch = new CountDownLatch();
        new Thread(new Teacher(countDownLatch)).start();
        new Thread(new Student(countDownLatch)).start();
        new Thread(new Student(countDownLatch)).start();
        new Thread(new Student(countDownLatch)).start();
        new Thread(new Student(countDownLatch)).start();
        countDownLatch.await(); // 线程阻塞

        System.out.println("考试开始!");
    }
}

class Teacher implements Runnable{

    private CountDownLatch countDownLatch;

    public Teacher(CountDownLatch countDownLatch) {
        this.countDownLatch = countDownLatch;
    }

    @Override
    public void run() {
        System.out.println("面试官到达考场!");
        countDownLatch.countDown(); // 线程计数减一
    }
}

class Student implements Runnable {

    private CountDownLatch countDownLatch;

    public Student(CountDownLatch countDownLatch) {
        this.countDownLatch = countDownLatch;
    }

    @Override
    public void run() {
        System.out.println("面试者到达考场!");
        countDownLatch.countDown();
    }
}
代码语言:javascript复制
CyclicBarrier

CyclicBarrier被称为栅栏

现场所有线程都到达指定地点之后在一起执行

例如所有运动员都到达起跑线发令枪响之后一起跑了出去


代码语言:javascript复制
package com.jmy.concurrent;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CyclicBarrier;

public class CyclicBarrierDemo {
    public static void main(String[] args) throws InterruptedException {
        CountDownLatch countDownLatch = new CountDownLatch();
        CyclicBarrier barrier = new CyclicBarrier();
        new Thread(new Sporter(barrier,countDownLatch)).start();
        new Thread(new Sporter(barrier,countDownLatch)).start();
        new Thread(new Sporter(barrier,countDownLatch)).start();
        new Thread(new Sporter(barrier,countDownLatch)).start();
        countDownLatch.await();

        System.out.println("枪响啦!");
    }
}

class Sporter implements Runnable {

    private CyclicBarrier barrier;
    private  CountDownLatch countDownLatch;
    public Sporter(CyclicBarrier barrier, CountDownLatch countDownLatch) {
        this.barrier = barrier;
        this.countDownLatch = countDownLatch;
    }

    @Override
    public void run() {

        countDownLatch.countDown();
        System.out.println("运动员到达起点");
        try {
            barrier.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (BrokenBarrierException e) {
            e.printStackTrace();
        }
        System.out.println("运动员跑了出去!");
    }
}
代码语言:javascript复制
Exchanger<T>

用于两个线程进行信息或者数据的交换

泛型表示要交换的信息类型

就是这么简单。。

0 人点赞