【JavaSE】Java基础语法(三十八):并发工具类

文章目录

  • 1. Hashtable
  • 2. ConcurrentHashMap基本使用
  • 3. ConcurrentHashMap1.7原理
  • 4. ConcurrentHashMap1.8原理
  • 5. CountDownLatch
  • 6. Semaphore


在这里插入图片描述

1. Hashtable

Hashtable出现的原因 : 在集合类中HashMap是比较常用的集合对象,但是HashMap是线程不安全的(多线程环境下可能会存在问题)。为了保证数据的安全性我们可以使用Hashtable,但是Hashtable的效率低下。

==代码实现 ==:

import java.util.HashMap;
import java.util.Hashtable;
public class MyHashtableDemo {
	public static void main(String[] args) throws InterruptedException {
		Hashtable<String, String> hm = new Hashtable<>();
		Thread t1 = new Thread(() -> {
			for (int i = 0; i < 25; i++) {
				hm.put(i + "", i + "");
			}
		});
		
		Thread t2 = new Thread(() -> {
			for (int i = 25; i < 51; i++) {
				hm.put(i + "", i + "");
			}
		});
		t1.start();
		t2.start();
		System.out.println("----------------------------");
		
		//为了t1和t2能把数据全部添加完毕
		Thread.sleep(1000);
		//0-0 1-1 ..... 50- 50
		for (int i = 0; i < 51; i++) {
			System.out.println(hm.get(i + ""));
		}//0 1 2 3 .... 50
	}
}

2. ConcurrentHashMap基本使用

ConcurrentHashMap出现的原因 : 在集合类中HashMap是比较常用的集合对象,但是HashMap是线程不安全的(多线程环境下可能会存在问题)。为了保证数据的安全性我们可以使用Hashtable,但是Hashtable的效率低下。

基于以上两个原因我们可以使用JDK1.5以后所提供的ConcurrentHashMap。

  • 体系结构 :
    在这里插入图片描述

  • 总结 :
    1 ,HashMap是线程不安全的。多线程环境下会有数据安全问题
    2 ,Hashtable是线程安全的,但是会将整张表锁起来,效率低下
    3,ConcurrentHashMap也是线程安全的,效率较高。 在JDK7和JDK8中,底层原理不一样。

  • 代码实现

    import java.util.Hashtable;
    import java.util.concurrent.ConcurrentHashMap;
    
    public class MyConcurrentHashMapDemo {
    	public static void main(String[] args) throws InterruptedException {
    		ConcurrentHashMap<String, String> hm = new ConcurrentHashMap<>(100);
    			Thread t1 = new Thread(() -> {
    			for (int i = 0; i < 25; i++) {
    				hm.put(i + "", i + "");
    			}
    		});
    		
    		Thread t2 = new Thread(() -> {
    			for (int i = 25; i < 51; i++) {
    				hm.put(i + "", i + "");
    			}
    		});
    		t1.start();
    		t2.start();
    		System.out.println("----------------------------");
    		
    		//为了t1和t2能把数据全部添加完毕
    		Thread.sleep(1000);
    		//0-0 1-1 ..... 50- 50
    		for (int i = 0; i < 51; i++) {
    			System.out.println(hm.get(i + ""));
    		}//0 1 2 3 .... 50
    	}
    }
    

3. ConcurrentHashMap1.7原理

在这里插入图片描述


4. ConcurrentHashMap1.8原理

在这里插入图片描述

总结 :
1,如果使用空参构造创建ConcurrentHashMap对象,则什么事情都不做。 在第一次添加元素的
时候创建哈希表
2,计算当前元素应存入的索引。
3,如果该索引位置为null,则利用cas算法,将本结点添加到数组中。
4,如果该索引位置不为null,则利用volatile关键字获得当前位置最新的结点地址,挂在他下面,变
成链表。
5,当链表的长度大于等于8时,自动转换成红黑树6,以链表或者红黑树头结点为锁对象,配合悲观
锁保证多线程操作集合时数据的安全性。


5. CountDownLatch

  • CountDownLatch类 :

在这里插入图片描述

  • 使用场景

    让某一条线程等待其他线程执行完毕之后再执行

  • 代码实现

    import java.util.concurrent.CountDownLatch;
    public class ChileThread1 extends Thread {
    	private CountDownLatch countDownLatch;
    	public ChileThread1(CountDownLatch countDownLatch) {
    		this.countDownLatch = countDownLatch;
    	}
    	
    	@Override
    	public void run() {
    		//1.吃饺子
    		for (int i = 1; i <= 10; i++) {
    			System.out.println(getName() + "在吃第" + i + "个饺子");
    		}
    		//2.吃完说一声
    		//每一次countDown方法的时候,就让计数器-1
    		countDownLatch.countDown();
    	}
    }
    
    import java.util.concurrent.CountDownLatch;
    public class ChileThread2 extends Thread {
    	private CountDownLatch countDownLatch;
    	public ChileThread2(CountDownLatch countDownLatch) {
    		this.countDownLatch = countDownLatch;
    	}
    	
    	@Override
    	public void run() {
    		//1.吃饺子
    		for (int i = 1; i <= 15; i++) {
    			System.out.println(getName() + "在吃第" + i + "个饺子");
    		}
    		
    		//2.吃完说一声
    		//每一次countDown方法的时候,就让计数器-1
    		countDownLatch.countDown();
    	}
    }
    
    import java.util.concurrent.CountDownLatch;
    public class ChileThread3 extends Thread {
    	private CountDownLatch countDownLatch;
    	public ChileThread3(CountDownLatch countDownLatch) {
    		this.countDownLatch = countDownLatch;
    	}
    	
    	@Override
    	public void run() {
    		//1.吃饺子
    		for (int i = 1; i <= 20; i++) {
    			System.out.println(getName() + "在吃第" + i + "个饺子");
    		}
    		
    		//2.吃完说一声
    		//每一次countDown方法的时候,就让计数器-1
    		countDownLatch.countDown();
    	}
    }
    
    import java.util.concurrent.CountDownLatch;
    public class MotherThread extends Thread {
    	private CountDownLatch countDownLatch;
    	public MotherThread(CountDownLatch countDownLatch) {
    		this.countDownLatch = countDownLatch;
    	}
    	
    	@Override
    	public void run() {
    		//1.等待
    			try {
    			//当计数器变成0的时候,会自动唤醒这里等待的线程。
    			countDownLatch.await();
    		} catch (InterruptedException e) {
    			e.printStackTrace();
    		}
    		//2.收拾碗筷
    		System.out.println("妈妈在收拾碗筷");
    	}
    }
    
    import java.util.concurrent.CountDownLatch;
    public class MyCountDownLatchDemo {
    	public static void main(String[] args) {
    		//1.创建CountDownLatch的对象,需要传递给四个线程。
    		//在底层就定义了一个计数器,此时计数器的值就是3
    		CountDownLatch countDownLatch = new CountDownLatch(3);
    		//2.创建四个线程对象并开启他们。
    		MotherThread motherThread = new MotherThread(countDownLatch);
    		motherThread.start();
    		ChileThread1 t1 = new ChileThread1(countDownLatch);
    		t1.setName("小明");
    		ChileThread2 t2 = new ChileThread2(countDownLatch);
    		t2.setName("小红");
    		ChileThread3 t3 = new ChileThread3(countDownLatch);
    		t3.setName("小刚");
    		t1.start();
    		t2.start();
    		t3.start();
    	}
    }
    
  • 总结 :

    1. CountDownLatch(int count):参数写等待线程的数量。并定义了一个计数器。
    2. await():让线程等待,当计数器为0时,会唤醒等待的线程
    3. countDown(): 线程执行完毕时调用,会将计数器-1。

6. Semaphore

  • 使用场景 :
    可以控制访问特定资源的线程数量。

  • 实现步骤 :
    1,需要有人管理这个通道
    2,当有车进来了,发通行许可证
    3,当车出去了,收回通行许可证
    4,如果通行许可证发完了,那么其他车辆只能等着

  • 代码实现 :

    import java.util.concurrent.Semaphore;
    public class MyRunnable implements Runnable {
    	//1.获得管理员对象,
    	private Semaphore semaphore = new Semaphore(2);
    	@Override
    	public void run() {
    		//2.获得通行证
    		try {
    			semaphore.acquire();
    			//3.开始行驶
    			System.out.println("获得了通行证开始行驶");
    			Thread.sleep(2000);
    			System.out.println("归还通行证");
    			//4.归还通行证
    			semaphore.release();
    		} catch (InterruptedException e) {
    			e.printStackTrace();
    		}
    	}
    }
    
    public class MySemaphoreDemo {
    	public static void main(String[] args) {
    	MyRunnable mr = new MyRunnable();
    	for (int i = 0; i < 100; i++) {
    		new Thread(mr).start();
    	}
    	}
    }
    

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/26244.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

CentOS7使用Docker快速安装Davinci

环境信息 操作系统&#xff1a;CentOS7Docker : 23.0.6 &#xff08;已配置阿里云镜像加速&#xff09; 安装步骤 安装docker-compose-plugin 官方的例子使用的是docker-compose&#xff0c;但是由于yum能够安装的最新斑斑是1.x,而且官方的docker-compose要求最低版本为2.2以…

如何在电脑上图片裁剪?裁剪图片大小的方法介绍

图片裁剪大小的优点 在数字化时代&#xff0c;图片已成为人们日常生活中使用最频繁的媒介之一。然而&#xff0c;由于不同尺寸和比例的图片在不同的平台上展示效果有所不同&#xff0c;因此需要对其进行裁剪。 图片裁剪大小的主要优点包括&#xff1a; 1. 优化页面显示&…

地震勘探基础(十)之地震速度关系

地震速度 地震勘探中引入了多种速度的概念&#xff0c;如下图所示。 层速度、平均速度和均方根速度之间的关系 层速度指的是某一套地层垂向上&#xff0c;由于地质条件相对稳定&#xff0c;地层顶底厚度比上地震波的传播时间为层速度&#xff0c;用 v n v_n vn​ 表示。 如下…

Eclipse教程 Ⅸ

今天继续来学习Eclipse 快速修复、Eclipse 浏览菜单、Eclipse 查找以及Eclipse 悬浮提示的内容&#xff01;老规矩&#xff0c;废话不多说&#xff0c;开始吧。 Eclipse 快速修复 使用快速修复 在 Eclipse 编辑器中当你输入字母时&#xff0c;编辑器会对你输入的内容进行错误…

Fiddler抓包工具配置+Jmeter基本使用

一、Fiddler抓包工具的配置和使用 在编写网关自动化脚本之前&#xff0c;得先学会如何抓包&#xff0c;这里以Fiddler为例。会抓包的同学可以跳过这一步&#xff0c;当然看看也是没坏处的…… 局域网络配置 将要进行抓包的手机与电脑连入同一局域网&#xff0c;电脑才能够…

CPU、内存、缓存的关系

术语解释 &#xff08;1&#xff09;CPU&#xff08;Central Processing Unit&#xff09; 中央处理器 &#xff08;2&#xff09;内存 内存用于暂时存放CPU中的运算数据&#xff0c;以及与硬盘等外部存储器交换的数据。它是外存与CPU进行沟通的桥梁&#xff0c;内存的运行决定…

生成式模型的质量评估标准

Sample Quality Matrix 如何评价生成式模型的效果&#xff1f;ISFIDsFIDPrecision & RecallPrecisonRecall计算precision和recall 如何评价生成式模型的效果&#xff1f; Quality: 真实性&#xff08;逼真&#xff0c;狗咬有四条腿&#xff09; Diversity: 多样性&#x…

Hive

Hive 概览 Hive是基于Hadoop的一个数据仓库工具&#xff0c;可以将结构化的数据文件映射为一张数据库表&#xff0c;并提供类SQL查询功能。 本质是将SQL转换为MapReduce程序。 主要用途&#xff1a;用来做离线数据分析&#xff0c;比直接用MapReduce开发效率更高。 架构 数…

机器视觉怎么对陶瓷板外观尺寸进行自动检测?

随着陶瓷行业的发展&#xff0c;陶瓷板的生产和质量控制面临越来越高的要求。而机器视觉技术作为一种高精度、高效率、无损、可靠性高的自动化检测手段&#xff0c;已经成为陶瓷板外观尺寸自动化检测的首选方案。本文就如何利用机器视觉对陶瓷板外观尺寸进行自动检测进行分析和…

常用模拟低通滤波器的设计——巴特沃斯滤波器

常用模拟低通滤波器的设计——巴特沃斯(Butterworth)滤波器 滤波器是一种具有频率选择作用的电路或运算处理系统&#xff0c;它具有区分区分输入信号的各种不同频率成分的功能&#xff0c;具有滤除噪声和分离各种不同信号的功能。综合一个滤波器的基本步骤分为逼近和实现。逼近…

设计模式之~享元模式

定义&#xff1a; 享元模式英文称为“Flyweight Pattern”&#xff0c;又译为羽量级模式或者蝇量级模式。 享元模式&#xff08;Flyweight Pattern&#xff09;主要用于减少创建对象的数量&#xff0c;以减少内存占用和提高性能。这种类型的设计模式属于结构型模式&#xff0c…

【每日挠头算法题(1)】——旋转字符串|亲密字符串

文章目录 一、旋转字符串思路1思路2 二、亲密字符串思路 总结 一、旋转字符串 点我直达终点~ 思路1 前提&#xff1a;如果s串和goal串长度不等&#xff0c;则goal串不可能是s串旋转得来&#xff0c;直接返回false&#xff1b; 通过观察&#xff0c;可以发现每旋转一次&#…

多线程屏障CyclicBarrier

文章目录 前言一、CyclicBarrier可以做什么&#xff1f;二、使用步骤1 单参数CyclicBarrier2 多参数 CyclicBarrier3 与CyclicBarrier类似的Exchanger 总结 前言 多线程中的CyclicBarrier,同样也是juc包下的一个工具类; 一、CyclicBarrier可以做什么&#xff1f; CyclicBarri…

一款开源的无线CMSIS DAP ARM芯片下载调试器详细说明

文章目录 概要1. 一般概念1.1 CMSIS—DAP的一般概念1.2 支持的芯片1.3 典型应用场景 2. 原理图与尺寸图2.1 Host端&#xff08;发送端&#xff09;原理图2.2 Target&#xff08;目标&#xff09;端原理图2.3 Host尺寸图2.4 Target尺寸图2.5 实物图 3. 使用方法3.1 连接方法3.1.…

4-5.配置信息和路由信息

一、配置信息 app.run()的参数 参数1&#xff1a;host&#xff0c;如果我们不指定&#xff0c;默认值是127.0.0.1。参数2&#xff1a;port&#xff0c;如果我们不指定&#xff0c;默认值是5000。参数3&#xff1a;debug&#xff0c;调试模式&#xff0c;如果不指定&#xff0…

电力系统直流潮流计算研究【IEEE9节点】(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

皮卡丘反射型XSS

1.反射型xss(get) 进入反射型xss(get)的关卡&#xff0c;我们可以看到如下页面 先输入合法数据查看情况&#xff0c;例如输入“kobe” 再随便输入一个&#xff0c;比如我舍友的外号“xunlei”&#xff0c;“666”&#xff0c;嘿嘿嘿 F12查看源代码&#xff0c;发现你输入的数…

什么是SOME/IP?

SOME/IP 是"Scalable service-Oriented MiddlewarE over IP"的缩写&#xff0c;即可扩展的面向服务的IP中间件&#xff0c;由AUTOSAR发布。它是一种自动/嵌入式通信协议&#xff0c;它支持远程过程调用、事件通知和底层序列化/线格式。唯一有效的缩写是SOME/IP&#…

软件测试想要高薪资,不仅要卷还要学会跳槽

都说00后躺平了&#xff0c;但是有一说一&#xff0c;该卷的还是卷。 这不&#xff0c;前段时间我们公司来了个00后&#xff0c;工作都没两年&#xff0c;跳槽到我们公司起薪20K&#xff0c;都快接近我了。后来才知道人家是个卷王&#xff0c;从早干到晚就差搬张床到工位睡觉了…

正在破坏您的协程(Coroutines)的无声杀手(Silent Killer)

正在破坏您的协程的无声杀手 处理 Kotlin 中的取消异常的唯一安全方法是不重新抛出它们。 今天生产服务器再次停止响应流量。 上个星期&#xff0c;你刚重新启动它们并将其视为故障。但是你总觉得有些奇怪&#xff0c;因为日志中没有任何错误的痕迹&#xff0c;甚至没有警告。…