当前位置:网站首页>涨姿势了!原来这才是多线程正确实现方式
涨姿势了!原来这才是多线程正确实现方式
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获得了锁"); } } } } }}
边栏推荐
猜你喜欢

Leetcode刷题——二叉搜索树相关题目(98. 验证二叉搜索树、235. 二叉搜索树的最近公共祖先、1038. 从二叉搜索树到更大和树、538. 把二叉搜索树转换为累加树)

微信公众号之底部菜单

深度学习------pytorch-gpu环境搭建

【地平线旭日X3派试用体验】从开机到点灯(第一节)

强烈推荐一款优秀且通用的后台管理系统

【VBox】解决复制VBox虚拟机后提示硬盘UUID 已经存在的问题

中电金信技术实践|分布式事务简说

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

ECCV 2022 | 清华&腾讯AI Lab提出REALY: 重新思考3D人脸重建的评估方法

Leetcode刷题——543. 二叉树的直径、617. 合并二叉树(递归解决)
随机推荐
国际原子能机构总干事警告称扎波罗热核电站安全形势已“完全失控”
小程序实战(一)- 骨架屏的应用与实现
你知道吗?那些专属于代码的浪漫~
win8和win10下,visual studio 2008 调试出现无响应的卡死问题解决
使用函数
【黄啊码】MySQL入门—1、SQL 的执行流程
深度学习------pytorch实现划拳模型训练
关于架构的思考
MySQL 45 讲 | 10 MySQL为什么有时候会选错索引?
ESP8266-Arduino编程实例-TSL2561亮度传感器驱动
【黄啊码】MySQL入门—2、使用数据定义语言(DDL)操作数据库
强烈推荐一款优秀且通用的后台管理系统
超美星空特效,你Get了吗?
*W3C* 标准组织
萌宠来袭,如何让“吸猫撸狗”更有保障?
Leetcode刷题——路径总和
知网网站地址更换
蒲丰投针学习笔记
ORA-00054 资源正忙
手搓一个“七夕限定”,用3D Engine 5分钟实现烟花绽放效果