1.Semaphore(信号量)

信号量数量限制了访问资源的线程总数,线程请求会消耗一个信号量,当信号量为0时,新的线程会阻塞,直到有线程释放了一个信号量

线程类:

package Semaphore;

import java.util.concurrent.Semaphore;

public class SemaphoreThread extends Thread{

Semaphore semaphore;

public SemaphoreThread(Semaphore semaphore){

this.semaphore = semaphore;

}

@Override

public void run() {

try {

semaphore.acquire();

System.out.println("一个线程正在执行");

sleep(3000);

System.out.println("一个线程结束运行");

} catch (InterruptedException e) {

e.printStackTrace();

}

semaphore.release();

}

}

测试类:

package Semaphore;

import java.util.concurrent.Semaphore;

public class MainClass {

public static void main(String[] args) {

Semaphore semaphore = new Semaphore(3);

SemaphoreThread t1 = new SemaphoreThread(semaphore);

SemaphoreThread t2 = new SemaphoreThread(semaphore);

SemaphoreThread t3 = new SemaphoreThread(semaphore);

SemaphoreThread t4 = new SemaphoreThread(semaphore);

SemaphoreThread t5 = new SemaphoreThread(semaphore);

SemaphoreThread t6 = new SemaphoreThread(semaphore);

t1.start();

t2.start();

t3.start();

t4.start();

t5.start();

t6.start();

}

}

运行结果:

一个线程正在执行

一个线程正在执行

一个线程正在执行

一个线程结束运行

一个线程结束运行

一个线程正在执行

一个线程正在执行

一个线程结束运行

一个线程正在执行

一个线程结束运行

一个线程结束运行

一个线程结束运行

Process finished with exit code 0

可以看到,由于我们把信号量数量设置为3,所以最多只能有3个线程在同时执行

2.CountDownLatch(倒计时门栓)

每完成一次特定操作,倒计时减一,线程集需要等到倒计时为0时才可执行。注意倒计时门栓是一次性的,计数为0后就不能再用了

线程类:

package CountDownLatch;

import java.util.concurrent.CountDownLatch;

public class CountDownLatchThread extends Thread {

CountDownLatch countDownLatch;

public CountDownLatchThread(CountDownLatch countDownLatch){

this.countDownLatch = countDownLatch;

}

@Override

public void run() {

System.out.println("一个线程正在等待");

try {

countDownLatch.await();

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println("一个线程结束等待");

}

}

测试类:

package CountDownLatch;

import java.util.concurrent.CountDownLatch;

public class MainClass {

public static void main(String[] args) {

CountDownLatch countDownLatch = new CountDownLatch(3);

CountDownLatchThread t1 = new CountDownLatchThread(countDownLatch);

CountDownLatchThread t2 = new CountDownLatchThread(countDownLatch);

CountDownLatchThread t3 = new CountDownLatchThread(countDownLatch);

t1.start();

t2.start();

t3.start();

try {

System.out.println("计数减一");

Thread.sleep(1000);

countDownLatch.countDown();

System.out.println("计数减一");

Thread.sleep(1000);

countDownLatch.countDown();

System.out.println("计数减一");

Thread.sleep(1000);

countDownLatch.countDown();

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

运行结果:

计数减一

一个线程正在等待

一个线程正在等待

一个线程正在等待

计数减一

计数减一

一个线程结束等待

一个线程结束等待

一个线程结束等待

Process finished with exit code 0

可以看到,由于我们把计时器设置为3,所以需要经过三次计数减一操作之后,线程集才可执行

3.CyclicBarrier(循环障栅)

线程在障栅处等待,当等待线程凑够一定数量后,打开障栅,放行这些线程,并执行阶段处理方法,然后重新关闭障栅

线程类:

package CyclicBarrier;

import java.util.concurrent.BrokenBarrierException;

import java.util.concurrent.CyclicBarrier;

public class CyclicBarrierThread extends Thread {

CyclicBarrier cyclicBarrier;

public CyclicBarrierThread(CyclicBarrier cyclicBarrier) {

this.cyclicBarrier = cyclicBarrier;

}

@Override

public void run() {

System.out.println("正在等待");

try {

cyclicBarrier.await();

} catch (InterruptedException e) {

e.printStackTrace();

} catch (BrokenBarrierException e) {

e.printStackTrace();

}

System.out.println("开始执行");

}

}

阶段处理方法:

package CyclicBarrier;

public class Deal implements Runnable {

@Override

public void run() {

System.out.println("打开障栅");

}

}

测试类:

package CyclicBarrier;

import java.util.concurrent.CyclicBarrier;

public class MainClass {

public static void main(String[] args) {

CyclicBarrier cyclicBarrier = new CyclicBarrier(2, new Deal());

CyclicBarrierThread t1 = new CyclicBarrierThread(cyclicBarrier);

CyclicBarrierThread t2 = new CyclicBarrierThread(cyclicBarrier);

CyclicBarrierThread t3 = new CyclicBarrierThread(cyclicBarrier);

CyclicBarrierThread t4 = new CyclicBarrierThread(cyclicBarrier);

CyclicBarrierThread t5 = new CyclicBarrierThread(cyclicBarrier);

try {

t1.start();

Thread.sleep(2000);

t2.start();

Thread.sleep(2000);

t3.start();

Thread.sleep(2000);

t4.start();

Thread.sleep(2000);

t5.start();

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

运行结果:

正在等待

正在等待

打开障栅

开始执行

开始执行

正在等待

正在等待

打开障栅

开始执行

开始执行

正在等待

可以看到,由于我们把障栅大小设置为2,所以当等待线程到达2个时就打开障栅放行。由于我们只有5个线程,所以最后一个线程会一直在障栅处等待

4.Phaser(阶段器)

在循环障栅的基础上增加了控制器,可以在循环若干个阶段后拆除障栅。线程需要注册阶段器,当请求等待线程数等于注册线程数时,打开障栅,执行阶段处理方法,阶段处理方法返回true时拆除障栅。

线程类1:

package Phaser;

import java.util.concurrent.Phaser;

public class Thread1 extends Thread {

Phaser phaser;

public Thread1(Phaser phaser) {

this.phaser = phaser;

phaser.register();

}

@Override

public void run() {

System.out.println("等待中");

phaser.arriveAndAwaitAdvance();

System.out.println("等待中");

phaser.arriveAndAwaitAdvance();

System.out.println("注销");

phaser.arriveAndDeregister();

}

}

线程类2:

package Phaser;

import java.util.concurrent.Phaser;

public class Thread2 extends Thread {

Phaser phaser;

public Thread2(Phaser phaser) {

this.phaser = phaser;

phaser.register();

}

@Override

public void run() {

System.out.println("等待中");

phaser.arriveAndAwaitAdvance();

System.out.println("等待中");

phaser.arriveAndAwaitAdvance();

System.out.println("等待中");

phaser.arriveAndAwaitAdvance();

System.out.println("注销");

phaser.arriveAndDeregister();

}

}

测试类:

package Phaser;

import java.util.concurrent.Phaser;

public class MainClass {

public static void main(String[] args) {

Phaser phaser = new Phaser() {

@Override

protected boolean onAdvance(int phase, int registeredParties) {

try {

System.out.println("一个阶段完成,注册线程数量:" + registeredParties + ",第" + phase + "阶段");

Thread.sleep(2000);

} catch (InterruptedException e) {

e.printStackTrace();

}

return registeredParties == 1;

}

};

Thread1 t1 = new Thread1(phaser);

Thread2 t2 = new Thread2(phaser);

t1.start();

t2.start();

}

}

运行结果:

等待中

等待中

一个阶段完成,注册线程数量:2,第0阶段

等待中

等待中

一个阶段完成,注册线程数量:2,第1阶段

注销

等待中

一个阶段完成,注册线程数量:1,第2阶段

注销

Process finished with exit code 0

可以看到只有等待线程数目等于注册线程数目时,才会打开障栅,完成一个阶段。由于我们的设置是当注册线程数为1时拆除障栅,所以第2阶段完成后就拆除了障栅,不会再有第3阶段

5.Exchanger(交换器)

两个线程之间交换数据,注意必须成对线程才可交换,如果有单个线程无法成对就会一直阻塞

线程一:

package Exchanger;

import java.util.concurrent.Exchanger;

public class Thread1 extends Thread {

Exchanger exchanger;

public Thread1(Exchanger exchanger){

this.exchanger = exchanger;

}

@Override

public void run() {

System.out.println("线程1写入数据1");

try {

System.out.println("线程1获得数据:"+exchanger.exchange("1"));

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

线程二:

package Exchanger;

import java.util.concurrent.Exchanger;

public class Thread2 extends Thread {

Exchanger exchanger;

public Thread2(Exchanger exchanger){

this.exchanger = exchanger;

}

@Override

public void run() {

System.out.println("线程2写入数据2");

try {

sleep(2000);

System.out.println("线程2获得数据:"+exchanger.exchange("2"));

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

线程三:

package Exchanger;

import java.util.concurrent.Exchanger;

public class Thread3 extends Thread {

Exchanger exchanger;

public Thread3(Exchanger exchanger){

this.exchanger = exchanger;

}

@Override

public void run() {

System.out.println("线程3写入数据3");

try {

System.out.println("线程3获得数据:"+exchanger.exchange("3"));

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

测试类:

package Exchanger;

import java.util.concurrent.Exchanger;

public class MainClass {

public static void main(String[] args) {

Exchanger exchanger = new Exchanger();

Thread1 t1 = new Thread1(exchanger);

Thread2 t2 = new Thread2(exchanger);

Thread3 t3 = new Thread3(exchanger);

t1.start();

t2.start();

t3.start();

}

}

运行结果:

线程1写入数据1

线程2写入数据2

线程3写入数据3

线程3获得数据:1

线程1获得数据:3

由于我们人为让线程2休眠了2秒,所以线程1和线程3先准备好并交换了数据,线程2就一直处于阻塞状态

6.SynchronousQueue(同步队列)

当一个线程调用put方法时,它会一直阻塞直到另一个线程调用take方法,与Exchanger类似,但Exchanger数据双向传递,SynchronousQueue数据单向传递

java 倒计时门栓,同步器相关推荐

  1. 使用线程自己join自己完成线程门栓

    public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(new R ...

  2. 基于JAVA政府机关门禁管理系统计算机毕业设计源码+系统+数据库+lw文档+部署

    基于JAVA政府机关门禁管理系统计算机毕业设计源码+系统+数据库+lw文档+部署 基于JAVA政府机关门禁管理系统计算机毕业设计源码+系统+数据库+lw文档+部署 本源码技术栈: 项目架构:B/S架构 ...

  3. 【附源码】计算机毕业设计JAVA政府机关门禁管理系统

    [附源码]计算机毕业设计JAVA政府机关门禁管理系统 目运行 环境项配置: Jdk1.8 + Tomcat8.5 + Mysql + HBuilderX(Webstorm也行)+ Eclispe(In ...

  4. java程序报告门禁系统_基于JAVA的门禁管理系统(含源文件).doc

    基于JAVA的门禁管理系统 学 生 姓 名: 学 院: 专 业: 班 级: 学 号: 指 导 教 师: 完 成 日 期: 摘 要 随着社会经济和科技的发展,IC卡技术已广泛地应用于各种行业,特别是公共 ...

  5. 打开Java之门——一个Java SE小白的学习日志1【极客BOY-米奇】

    文章目录 前言(转载请说明作者:极客BOY) 打开Java之门 Why learn Java? Java's History What's the "Java JDK"? Theo ...

  6. java倒计时,定时器

    一.Java倒计时,使用timer实现 /*** 倒计时** @param min 倒计时间(分钟)*/ public void CountDown(int min) {//开始时间long star ...

  7. Java中的队列同步器AQS

    一.AQS概念 1.队列同步器是用来构建锁或者其他同步组件的基础框架,使用一个int型变量代表同步状态,通过内置的队列来完成线程的排队工作. 2.下面是JDK8文档中对于AQS的部分介绍 public ...

  8. java 倒计时_java倒计时器

    [java]代码库import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; /** * 倒计时 ...

  9. 对java这门课程的认识_关于java课程的总结

    前言 本次博客主要内容为此次三次作业的总结,整门java课程学习的总结,以及在此次java课程中的收获,和对课程的意见. 作业过程总结 第一次作业主要考察的是对程序的可扩展性,实现开闭原则非常重要,因 ...

最新文章

  1. Ignoring unused library classes...java.io.IOException: You have to specify '-keep' options for the s
  2. Office 365发送超大附件
  3. halcon File文件算子,持续更新
  4. HALCON示例程序classify_image_class_svm.hdev使用SVM分类器对多通道图像进行分类
  5. 微软启动了自爆程序,让我们一起帮它倒计时
  6. 今日头条Java后台Java研发三面题目
  7. mysql未找到bcrypt_使用mysql和bcryptjs时出现意外的标识符语法错误
  8. oracle insert select 大 批量 数据_芬兰 Vaisala维萨拉 HM70手持式温湿度表 型号:FL15/HM70+HMP75【北京中西华大吧】...
  9. 爬get接口_网络字体反爬之起点中文小说
  10. java 字符 次数_java-统计字符串中各字符次数
  11. 达拉草201771010105《面向对象程序设计(java)》第十七周学习总结
  12. Unity 制作RPG小地图
  13. 【统计学】三大相关系数之斯皮尔曼相关系数(spearman correlation coefficient)
  14. 混响延迟插件9个合集 – ValhallaDSP Bundle 2020 WiN 免安装版
  15. Serializable serialVersionUID作用
  16. 算法设计与分析第五章习题解答与学习指导(第2版)屈婉婷 刘田 张立昂 王捍贫编著 清华大学出版社
  17. 2021-10-18记录 MediaTek MT7620A 平台对应的类型
  18. 穿山甲android对接错误码40029,空Android项目集成Cocos、穿山甲。Lua调用网络接口。...
  19. NVD软件漏洞数据处理及分类方法总结
  20. 湖北省安陆市发展怎么样

热门文章

  1. 如何检查字符串是否包含特定的单词? [英]How do I check if a string contains a specific word?
  2. 【报告分享】完美日记品牌分析报告.pdf(附68页pdf全文下载链接)
  3. 软件设计师学习3——操作系统知识
  4. GPT Plus Money!B O O M
  5. 使用方法_山西硅肥使用方法
  6. python物体跟着鼠标走_用Python写一个跟随鼠标运动的自定义窗口
  7. HDU3544 不平等博弈
  8. Excel关于宏的运用
  9. Babylon-AST初探-代码生成(Create)
  10. ota编译及差分包制作