Java多线程(7):并发_线程同步_队列与锁(Synchronized)

2023-11-20

一、并发举例(线程不安全)

1、两个人同时操作一张银行卡,如何保证线程安全。
2、多个人同时购买一张火车票,谁能买到?

二、并发特点

1、同一个对象
2、被多个线程操作
3、同时操作

三、如何保证线程安全:线程同步(队列+锁)

1、使用队列的技术一个一个对资源进行操作,并通过一定算法决定谁先使用,例如一个班级只有一台电脑,那么排队一个一个操作。
2、对象的锁:如果当前资源被占用则锁上。

四、线程同步方法

1、synchronized关键字包括两种用法:synchronized方法和synchronized
2、synchronized方法:若将一个大的方法声明为synchronized将会大大影响效率,比如一个方法内两个属性A和B,A属性提供只读功能,B属性可修改需要锁住,那么如果一个方法都设置为synchronized则A也无法访问则影响了效率。方法锁

	public class Synchronized {
		public static void main(String[] args) {
			
			SafeWeb12306 safe = new SafeWeb12306();
			new Thread(safe,"bull1").start();
			new Thread(safe,"bull2").start();
			new Thread(safe,"bull3").start();
		}
	}
	
	
	class SafeWeb12306 implements Runnable{
		
		private int ticketNum = 10;
		private boolean flag = true;
		
		@Override
		public void run() {
			while(flag) {
				test();
				
			}
			
		}
		
		
		public synchronized void test() {
			if(ticketNum<=0) {
				flag = false;
				return;
			}
			
			try {
				Thread.sleep(200);
			} catch (InterruptedException e) {
				
				e.printStackTrace();
			}
			System.out.println(Thread.currentThread().getName()+"-->"+(ticketNum--));
		}
	}

3、synchronized块可以只锁住一部分。下面的例子直接锁住账户而不是锁住方法,这里的方法就相当于取款机,锁住取款机是没用的,只能锁住账户。
synchronized块的表示方法:

synchronized(object){}
	public class Synchronized2 {
	
	
	public static void main(String[] args) {
		Account account = new Account(1000,"结婚礼金");
		Drawing me = new Drawing(account,80,"自己");
		Drawing you = new Drawing(account,90,"媳妇儿");
		new Thread(me,"自己").start();
		new Thread(you,"媳妇儿").start();
	}
}


class Account{
	int money;
	String name;
	 public Account(int money,String name) {
		this.money = money;
		this.name = name;
	}
	 
}


class Drawing implements Runnable{
	
	Account account ;
	int drawMoney;
	int pocketMoney=0;
	@Override
	public void run() {
		try {
			Thread.sleep(300);
		} catch (InterruptedException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}
		test();
	}
	
	
	public Drawing(Account account,int drawMoney,String name) {
		// TODO 自动生成的构造函数存根

		this.account = account;
		this.drawMoney = drawMoney;
		
	}
	
	
	
	public  void test() {
		//非常重要的一个判断,可以提高效率
		if(account.money<=0) {
			return;
		}
		
		
		synchronized (account) {
			if(account.money-drawMoney<0) {
				System.out.println(Thread.currentThread().getName()+"取钱余额不足");
				return;
			}
			
			try {
				Thread.sleep(200);
			} catch (InterruptedException e) {
				// TODO 自动生成的 catch 块
				e.printStackTrace();
			}
			
			account.money -= drawMoney;
			pocketMoney += drawMoney;
			
			System.out.println(Thread.currentThread().getName()+"账户里还剩-->"+account.money);
			System.out.println(Thread.currentThread().getName()+"口袋里还有-->"+pocketMoney);
		}
		
	}
}

五、同步块

1、synchronized (obj){}:其中obj称为同步监视器。
2、同步方法中无需指定同步监视器,因为同步方法的同步监视器是this即该对象本身,或class即类的模子。
3、同步监视器的执行过程:
(1)第一个线程访问时,锁定同步监视器,执行其中代码。
(2)第二个线程访问,发现同步监视器被锁定,无法访问。
(3)第一个线程访问完毕,解锁同步监视器。
(4)第二个线程访问发现同步监视器未锁定,锁定并访问。
4、要锁住不变的对象,时刻在变的属性之类的东西不能锁

六、同步块模拟抢票

	public class SynWeb12306 {
		public static void main(String[] args) {
			Ticket ticket = new Ticket();
			new Thread(ticket,"bull1").start();
			new Thread(ticket,"bull2").start();
			new Thread(ticket,"bull3").start();
			new Thread(ticket,"bull4").start();
			new Thread(ticket,"bull5").start();
		}
		
	}
	
	
	class Ticket implements Runnable{
		private int ticketNum = 30;
		private boolean flag = true;
		
		@Override
		public void run() {
			try {
				Thread.sleep(200);
			} catch (InterruptedException e) {
				// TODO 自动生成的 catch 块
				e.printStackTrace();
			}
			while(flag) {
				test();
			}
			
		}
		
		public  void test() {
			
			synchronized (this) {					//锁住对象本身,如果只锁定ticketNum不行,因为他一直在变,锁定不变的东西
				if(ticketNum<=0) {
					flag = false;
					return;
				}
				try {
					Thread.sleep(200);
				} catch (InterruptedException e) {
					// TODO 自动生成的 catch 块
					e.printStackTrace();
				}
				System.out.println(Thread.currentThread().getName()+"-->"+ticketNum--);
			}
			
		}
	}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java多线程(7):并发_线程同步_队列与锁(Synchronized) 的相关文章

随机推荐

  • MySQL之数据类型

    目录 一 MySQL数据类型分类 二 数值类型 1 整数类型 2 bit类型 3 小数类型 三 字符串类型 1 char 2 varchar 3 char和varchar比较 四 日期和时间类型 五 enum和set 一 MySQL数据类型
  • C#短信接口开发经验及具体开发实现

    一 配置文件app config
  • Unicode编码小结

    Unicode编码 一 ASCLL码 ASCII American Standard Code for Information Interchange 美国信息交换标准代码 是基于拉丁字母的一套电脑编码系统 主要用于显示现代英语和其他西欧语
  • Flutter 扫描插件开发qrscan

    首先在pubspec yaml中集成 dependencies qrscan 0 2 17 在androd清单文件中加入以下权限
  • Ubuntu安装X11

    Qt实现linux无边框界面需要用到Xlib 安装X11命令如下 sudo apt get install libx11 dev libxext dev libxtst dev libxrender dev libxmu dev libxm
  • align-content 设置多行下的子元素排列方式 代码和图片展示

    align content 适用于 换行 多行 的情况下 单行无效 可以设置上对齐 居中拉伸和平均分配剩余空间等属性值 属性值 flex start 默认值 在侧轴头部开始排列 flex end 在侧轴尾部开始排列 center 在侧轴中间
  • 编程练习3-将文件a处理为文件b

    初始文件a txt a b c d e f o p q r s t 处理后文件b txt a b a b c d a b c d e f o p o p q r o p q r s t shell bin bash array1 awk p
  • 虚拟主机的数据库服务器怎么填,虚拟主机的数据库服务器怎么填

    虚拟主机的数据库服务器怎么填 内容精选 换一换 云服务器备份 云服务器备份可以对普通服务器进行整机备份或部分磁盘备份 不适用于部署了数据库等应用的服务器 支持备份弹性云服务器ECS和裸金属服务器BMS 成本相对于VBS较高 适合对需要备份整
  • anaconda 创建虚拟环境

    创建虚拟环境 conda create n 名字 python 版本号 e g conda create n test python 3 10 删除虚拟环境 conda remove n 名字 all e g conda remove n
  • 大数据之hive(数据仓库工具)的分组和分区操作

    注 在对hive的概念 优缺点 安装部署和参数配置在之后再进行总结 本小节主要对hive中的分组和分区进行总结 一 分组 1 group by语句 group by通常和聚合函数一起使用 按照一个或者多个列进行分组 然后对每个组进行聚合操作
  • Visual Studio 将json转换为实体类

    先复制你的json文本然后
  • JDK源码 --

    Object类 一 简介 gt java lang Object 是Java所有类的父类 在你编写一个类的时候 若无指定父类 没有显式extends一个父类 会默认的添加Object为该类的父类 在JDK 6之前是编译器处理 即编译后的zc
  • 【Python中线程和进程详解】

    一 区别 几乎所有的操作系统都支持同时运行多个任务 每个任务通常是一个程序 每一个运行中的程序就是一个进程 即进程是应用程序的执行实例 现代的操作系统几乎都支持多进程并发执行 注意 并发和并行是两个概念 并行指在同一时刻有多条指令在多个处理
  • 配置NFS服务器-debian

    NFS Network Files System 是网络文件系统的英文缩写 由Sun公司于1980年开发 用于在UNIX操作系统间实现磁盘文件共享 在Linux操作系统出现后 NFS被Linux继承 并成为文件服务的一种标准 通过网络 NF
  • 施耐德电气携中国信通院和中国联通共同发布白皮书,共探5G+PLC深度融合应用

    2023年9月20日 全球能源管理和自动化领域的数字化转型专家施耐德电气在第23届中国国际工业博览会首日的9月19日 与中国信息通信研究院 以下简称 中国信通院 及中国联合网络通信集团有限公司 以下简称 中国联通 联手重磅发布 5G PLC
  • 6.SSH框架整合及简单使用示例

    6 SSH框架整合 ssh spring spring mvc hibernate 6 1 整合的场所 web xml 跟 5 ssm框架 整合类似 可以对照学习 通过监听器配置hibernate 通过servlet配置mvc web xm
  • 设计模式之观察者模式(Observer)摘录

    23种GOF设计模式一般分为三大类 创建型模式 结构型模式 行为模式 创建型模式抽象了实例化过程 它们帮助一个系统独立于如何创建 组合和表示它的那些对象 一个类创建型模式使用继承改变被实例化的类 而一个对象创建型模式将实例化委托给另一个对象
  • 2021蓝桥杯模拟赛-跳跃

    题目 题目链接 题解 动态规划 算是比较基础的状态方程和状态定义 但是难点在于处理负权重的情况 代码 include
  • 通过微信小程序实现登录功能

    后端服务器可以在CSDN上开通 价格优惠 CSDN开发云 https img home csdnimg cn images 20220518054835 png https dev csdn net activity utm source
  • Java多线程(7):并发_线程同步_队列与锁(Synchronized)

    一 并发举例 线程不安全 1 两个人同时操作一张银行卡 如何保证线程安全 2 多个人同时购买一张火车票 谁能买到 二 并发特点 1 同一个对象 2 被多个线程操作 3 同时操作 三 如何保证线程安全 线程同步 队列 锁 1 使用队列的技术一