当前位置:网站首页>涨姿势了!原来这才是多线程正确实现方式
涨姿势了!原来这才是多线程正确实现方式
2022-08-04 11:31:00 【InfoQ】
Java内存模型


线程同步
锁概述

锁的作用
锁的相关概念
可重入性:一个线程持有该锁的时候能够再次/多次申请该锁
锁的争用与调度
锁的粒度
内部锁:Synchronized
Synchronized(对象锁){ 同步代码块,可以在同步代码块中访问共享数据}
Synchronized同步代码块
public class SynchronizedLock { public static void main(String[] args) { SynchronizedLock synchronizedLock=new SynchronizedLock(); for (int i = 0; i <2 ; i++) { new Thread(new RunnableThread()) { @Override public void run() { synchronizedLock.mm(); } }.start(); } } public void mm() { for (int i = 0; i <100 ; i++) { System.out.println(Thread.currentThread().getName()+"-->"+i); } }}

public class SynchronizedLock { public static void main(String[] args) { SynchronizedLock synchronizedLock=new SynchronizedLock(); for (int i = 0; i <2 ; i++) { new Thread(new RunnableThread()) { @Override public void run() { synchronizedLock.mm();//使用锁的对象是synchronizedLock对象 } }.start(); } } public void mm() { synchronized (this)//this作为当前对象 { for (int i = 0; i <100 ; i++) { System.out.println(Thread.currentThread().getName()+"-->"+i); } } }}

锁对象不同不能实现同步
public class SynchronizedLock { public static void main(String[] args) { SynchronizedLock synchronizedLock=new SynchronizedLock(); SynchronizedLock synchronizedLock2=new SynchronizedLock(); new Thread(new RunnableThread()) { @Override public void run() { synchronizedLock.mm();//使用锁的对象是synchronizedLock对象 } }.start(); new Thread(new RunnableThread()) { @Override public void run() { synchronizedLock2.mm();//使用锁的对象是synchronizedLock对象 } }.start(); } public void mm() { synchronized (this)//this作为当前对象 { for (int i = 0; i <100 ; i++) { System.out.println(Thread.currentThread().getName()+"-->"+i); } } }}

使用常量作为锁对象
public class SynchronizedLock { public static void main(String[] args) { SynchronizedLock synchronizedLock=new SynchronizedLock(); SynchronizedLock synchronizedLock2=new SynchronizedLock(); new Thread(new RunnableThread()) { @Override public void run() { synchronizedLock.mm();//使用锁的对象是synchronizedLock对象 } }.start(); new Thread(new RunnableThread()) { @Override public void run() { synchronizedLock.mm();//使用锁的对象是synchronizedLock对象 } }.start(); } public static final Object obj=new Object(); public void mm() { synchronized (obj)//常量作为当前对象 { for (int i = 0; i <100 ; i++) { System.out.println(Thread.currentThread().getName()+"-->"+i); } } }}
同步实例方法
public class SynchronizedLock { public static void main(String[] args) { SynchronizedLock synchronizedLock=new SynchronizedLock(); new Thread(new RunnableThread()) { @Override public void run() { synchronizedLock.mm(); } }.start(); new Thread(new RunnableThread()) { @Override public void run() { synchronizedLock.mm2(); } }.start(); } //同步实例方法 public synchronized void mm() { for (int i = 0; i <100 ; i++) { System.out.println(Thread.currentThread().getName()+"-->"+i); } } public void mm2() { synchronized (this)//常量作为当前对象 { for (int i = 0; i <100 ; i++) { System.out.println(Thread.currentThread().getName()+"-->"+i); } } }}
同步静态方法
public class SynchronizedLock { public static void main(String[] args) { SynchronizedLock synchronizedLock=new SynchronizedLock(); new Thread(new RunnableThread()) { @Override public void run() { synchronizedLock.mm2(); } }.start(); new Thread(new RunnableThread()) { @Override public void run() { SynchronizedLock.mm();//使用锁的对象是SynchronizedLock.class } }.start(); } //同步静态方法 public synchronized static void mm() { for (int i = 0; i <100 ; i++) { System.out.println(Thread.currentThread().getName()+"-->"+i); } } public void mm2() { synchronized (SynchronizedLock.class)//常量作为当前对象 { for (int i = 0; i <100 ; i++) { System.out.println(Thread.currentThread().getName()+"-->"+i); } } }}
同步代码块和同步方法如何选择
public class SynchronizedLock { public static void main(String[] args) { SynchronizedLock synchronizedLock=new SynchronizedLock(); new Thread(new RunnableThread()) { @Override public void run() { try { synchronizedLock.mm2(); } catch (InterruptedException e) { e.printStackTrace(); } } }.start(); new Thread(new RunnableThread()) { @Override public void run() { try { synchronizedLock.mm2();//使用锁的对象是SynchronizedLock.class } catch (InterruptedException e) { e.printStackTrace(); } } }.start(); } //同步实例方法 锁的粒度粗 执行效率低 public synchronized void mm() throws InterruptedException { long starttime= System.currentTimeMillis(); System.out.println("start"); Thread.sleep(3000); for (int i = 0; i <100 ; i++) { System.out.println(Thread.currentThread().getName()+"-->"+i); } System.out.println("end"); long Endtime= System.currentTimeMillis(); System.out.println(Endtime-starttime); } //同步代码块 锁的粒度细 并发效率高 public void mm2() throws InterruptedException { System.out.println("start"); Thread.sleep(3000); synchronized (this)//常量作为当前对象 { for (int i = 0; i <100 ; i++) { System.out.println(Thread.currentThread().getName()+"-->"+i); } } System.out.println("end"); }}
脏读
public class Test06 { public static void main(String[] args) throws InterruptedException { User user=new User(); SubThread subThread=new SubThread(user); subThread.start(); user.GetName(); } static class SubThread extends Thread { public User user; public SubThread(User user) { this.user=user; } @Override public void run() { user.SetValue("ww","456"); } } static class User { private String name="ylc"; private String pwd="123"; public void GetName() { System.out.println(Thread.currentThread().getName()+"==>"+name+"密码"+pwd); } public void SetValue(String name,String pwd) { System.out.println("原来为为name="+this.name+",pwd="+this.pwd); this.name=name; this.pwd=pwd; System.out.println("更新为name="+name+",pwd="+pwd); } }}


线程出现异常释放锁
public class SynchronizedLock { public static void main(String[] args) { SynchronizedLock synchronizedLock=new SynchronizedLock(); new Thread(new RunnableThread()) { @Override public void run() { synchronizedLock.mm(); } }.start(); new Thread(new RunnableThread()) { @Override public void run() { synchronizedLock.mm2(); } }.start(); } //同步实例方法 public synchronized void mm() { for (int i = 0; i <100 ; i++) { if(i==50) { Integer.parseInt("abc");//异常设置 } System.out.println(Thread.currentThread().getName()+"-->"+i); } } public void mm2() { synchronized (this) { for (int i = 0; i <100 ; i++) { System.out.println(Thread.currentThread().getName()+"-->"+i); } } }}

死锁
public class Text06_5 { public static void main(String[] args) { SubThread subThread=new SubThread(); SubThread subThread2=new SubThread(); subThread.setName("a"); subThread2.setName("b"); subThread.start();subThread2.start(); } static class SubThread extends Thread { private static final Object lock1=new Object(); private static final Object lock2=new Object(); @Override public void run() { if("a".equals(Thread.currentThread().getName())) { synchronized (lock1) { System.out.println("a 线程 lock1获得了锁,再需要获得lock2"); synchronized (lock2) { System.out.println("a 线程 lock2获得了锁"); } } } if("b".equals(Thread.currentThread().getName())) { synchronized (lock2) { System.out.println("b 线程 lock2获得了锁,再需要获得lock1"); synchronized (lock1) { System.out.println(" b 线程 lock1获得了锁"); } } } } }}

边栏推荐
- 小程序实战(一)- 骨架屏的应用与实现
- SkiaSharp 之 WPF 自绘 粒子花园(案例版)
- 【Qt】解决 “由于找不到Qt5Cored.dll,无法继续执行代码”(亲测有效)
- Disc burning steps
- 临床研究方法学,到现场,到数据真实发生的地方 | 对话数智 x 张维拓
- BOSS直聘回应女大学生连遭两次性骚扰:高度重视求职者安全 可通过App等举报
- The sword refers to the Great Wall Cannon?Official spy photos of Changan's new pickup
- 【地平线旭日X3派试用体验】从开机到点灯(第一节)
- Mysql数据类型
- 使用json-server快速搭建本地数据接口
猜你喜欢
The use of DDR3 (Naive) in Xilinx VIVADO (2) Read and write design
vscode插件设置——Golang开发环境配置
Leetcode - using sequence traversal features first completed 114. The binary tree to the list
入门MySql表的增删查改
项目管理前景
字节技术官亲码算法面试进阶神技太香了
【黄啊码】MySQL入门—2、使用数据定义语言(DDL)操作数据库
【LeetCode】700.二叉搜索树
Redis查询缓存
HyperLynx仿真(一)LineSim简单介绍
随机推荐
Leetcode brush questions - binary search tree related topics (98. Verify binary search tree, 235. The nearest common ancestor of binary search tree, 1038. From binary search tree to bigger sum tree, 5
上帝空间——全球首个基于Web3.0的艺术协议创意平台,拓宽多元艺术融合边界
表的完整性约束;非外键约束
节流函数(每隔一段时间就会执行一次)
Leetcode刷题——路径总和
ESP8266-Arduino编程实例-MQ3酒精传感器驱动
深度强化学习与APS的一些感想
临床研究方法学,到现场,到数据真实发生的地方 | 对话数智 x 张维拓
Leetcode刷题——构造二叉树(105. 从前序与中序遍历序列构造二叉树、106. 从中序与后序遍历序列构造二叉树)
*SEO*
Zhihu Data Analysis Training Camp
The use of DDR3 (Naive) in Xilinx VIVADO (1) to create an IP core
DQL-查询操作
【无标题】
Move the blog to CSDN
asp.net解决大文件断点续传
MySQL 45 讲 | 11 怎么给字符串字段加索引?
章节小测一
你值得拥有的登录注册页面(附赠源码)
终于有人把分布式机器学习讲明白了