JAVA多线程(3)——如何加锁
1、加锁不正确导致数据不一致:m1执行过程中,m2(未加synchronized)可以执行,因为m2不用获得锁就可以执行
1 public class TT implements Runnable { 2 int b = 100; 3 4 public synchronized void m1() throws Exception { 5 b = 1000; 6 System.out.println("in m1() before sleep,b="+b); 7 Thread.sleep(5000); 8 System.out.println("in m1() after sleep,b="+b); 9 } 10 11 public void m2() { 12 //public synchronized void m2() throws Exception { 13 b = 199; 14 System.out.println("in m2(),b="+b); 15 } 16 17 public void run() { 18 try { 19 m1(); 20 } catch (Exception e) { 21 e.printStackTrace(); 22 } 23 } 24 25 public static void main(String[] args) throws Exception { 26 TT tt = new TT(); 27 System.out.println("in main() just after new TT(),b=" + tt.b); 28 Thread t = new Thread(tt); 29 t.start(); 30 31 Thread.sleep(1000); //为了让m1能够执行b=1000的赋值 32 tt.m2(); // 主线程执行m2 33 34 System.out.println("in main() last,b=" + tt.b); 35 } 36 }
结果:
D:\聚划算\技术部\编程练习\TestThread\Sync>java TT
in main() just after new TT(),b=100
in m1() before sleep,b=1000
in m2(),b=199
in main() last,b=199
in m1() after sleep,b=199 //main线程先于t线程结束吗?
说明:锁定当前对象 只是针对synchronized 这段话,另外的线程完全有可能访问没有锁定的方法(即不带synchronized 的方法)
问题:要保证对资源b的正确访问,需要考虑所有访问b的所有方法,是否需要加同步:加了同步效率可能变低、不加同步可能会出现数据不一致
问题:main线程先于t线程结束吗?
解答:会,main方法即使执行完最后的语句,JVM也不会结束该程序,要等到主线程中的所有其它线程都结束之后,才结束该JAVA应用程序
2、解决上述访问资源b,数据不一致的问题:把所有访问b的方法加锁,m1执行过程,m2一定执行不了,执行m2时必须要得到当前对象的锁才能执行
1 public class TT implements Runnable { 2 int b = 100; 3 4 public synchronized void m1() throws Exception { 5 b = 1000; 6 System.out.println("in m1() before sleep,b="+b); 7 Thread.sleep(5000); 8 System.out.println("in m1() after sleep,b="+b); 9 } 10 11 public synchronized void m2() { 12 //public synchronized void m2() throws Exception { 13 b = 199; 14 System.out.println("in m2(),b="+b); 15 } 16 17 public void run() { 18 try { 19 m1(); 20 } catch (Exception e) { 21 e.printStackTrace(); 22 } 23 } 24 25 public static void main(String[] args) throws Exception { 26 TT tt = new TT(); 27 System.out.println("in main() just after new TT(),b=" + tt.b); 28 Thread t = new Thread(tt); 29 t.start(); 30 31 Thread.sleep(1000); //为了让m1能够执行b=1000的赋值 32 tt.m2(); 33 34 System.out.println("in main() last,b=" + tt.b); 35 } 36 }
结果:
D:\聚划算\技术部\编程练习\TestThread\Sync>java TT
in main() just after new TT(),b=100
in m1() before sleep,b=1000
in m1() after sleep,b=1000 //m1执行完了才会执行m2
in m2(),b=199
in main() last,b=199
举例:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· 葡萄城 AI 搜索升级:DeepSeek 加持,客户体验更智能
· 什么是nginx的强缓存和协商缓存
· 一文读懂知识蒸馏