前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Concurrent包之lock

Concurrent包之lock

作者头像
姜同学
发布2022-10-27 16:35:30
1520
发布2022-10-27 16:35:30
举报
文章被收录于专栏:姜同学姜同学

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>

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

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

就是这么简单。。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-08-06T,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档