1、加锁不正确导致数据不一致:m1执行过程中,m2(未加synchronized)可以执行,因为m2不用获得锁就可以执行

1 public class TT implementsRunnable {2 int b = 100;3

4 public synchronized void m1() throwsException {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 voidm2() {12 //public synchronized void m2() throws Exception {

13 b = 199;14 System.out.println("in m2(),b="+b);15 }16

17 public voidrun() {18 try{19 m1();20 } catch(Exception e) {21 e.printStackTrace();22 }23 }24

25 public static void main(String[] args) throwsException {26 TT tt = newTT();27 System.out.println("in main() just after new TT(),b=" +tt.b);28 Thread t = newThread(tt);29 t.start();30

31 Thread.sleep(1000); //为了让m1能够执行b=1000的赋值

32 tt.m2(); // 主线程执行m233

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 implementsRunnable {2 int b = 100;3

4 public synchronized void m1() throwsException {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 voidm2() {12 //public synchronized void m2() throws Exception {

13 b = 199;14 System.out.println("in m2(),b="+b);15 }16

17 public voidrun() {18 try{19 m1();20 } catch(Exception e) {21 e.printStackTrace();22 }23 }24

25 public static void main(String[] args) throwsException {26 TT tt = newTT();27 System.out.println("in main() just after new TT(),b=" +tt.b);28 Thread t = newThread(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

举例:

如何加锁:——设定同步对象时较麻烦

数据库中的某一个记录,可以改、也可以读,一般情况下哪个方法应该加锁?

(1)读:允许多个线程同时读

(2)改:要加synchronized ,不允许两个线程同时改

java怎么加锁_JAVA多线程(3)——如何加锁相关推荐

  1. java线程钥匙_Java多线程并发编程/锁的理解

    一.前言 最近项目遇到多线程并发的情景(并发抢单&恢复库存并行),代码在正常情况下运行没有什么问题,在高并发压测下会出现:库存超发/总库存与sku库存对不上等各种问题. 在运用了 限流/加锁等 ...

  2. java 锁竞争_Java多线程中的竞争条件、锁以及同步的概念

    竞争条件 1.竞争条件: 在java多线程中,当两个或以上的线程对同一个数据进行操作的时候,可能会产生"竞争条件"的现象.这种现象产生的根本原因是因为多个线程在对同一个数据进行操作 ...

  3. java 多线程 串行 加锁_Java多线程(2)线程锁

    多线程访问同一个资源进行读写操作,就很容易出一些问题(比如我们常见的读者写者,生产者消费者模型)所以我们会选择对他们设置信号量或者加锁,来限制同一个时刻只有一个线程对某个对象进行操作. 多线程是一个蛮 ...

  4. java 多线程 串行 加锁_java多线程 synchronized 与lock锁 实现线程安全

    如果有多个线程在同时运行,而这些线程可能会同时运行这段代码.程序每次运行结果和单线程运行的结果是一样 的,而且其他的变量的值也和预期的是一样的,就是线程安全的. 通过卖火车票的例子 火车站要卖票,我们 ...

  5. c++该转java吗_java多线程,静态方法加锁后,调用该方法会影响其它方法吗?

    从一个问题说起 一直想要把一些学习历程和感悟记录下来,却没有静下心来好好思考一下,今天,就从同学问到的一个问题开始,对同一个类的静态方法加锁后,调用该方法,其他方法的调用会受到影响吗? 对象锁与类锁 ...

  6. java队列加锁_java并发-----浅析ReentrantLock加锁,解锁过程,公平锁非公平锁,AQS入门,CLH同步队列...

    前言 为什么需要去了解AQS,AQS,AbstractQueuedSynchronizer,即队列同步器.它是构建锁或者其他同步组件的基础框架(如ReentrantLock.ReentrantRead ...

  7. java添加锁_java – 如何在这种情况下添加锁?

    我几次遇到这种情况.你需要的是一个单独的LockFactory,它实际上是一个锁对象弱引用的字典.代码应该是这样的: class LockFactory { private LockFactory() ...

  8. java线程池_Java多线程并发:线程基本方法+线程池原理+阻塞队列原理技术分享...

    线程基本方法有哪些? 线程相关的基本方法有 wait,notify,notifyAll,sleep,join,yield 等. 线程等待(wait) 调用该方法的线程进入 WAITING 状态,只有等 ...

  9. java 缓存一致性_Java多线程——CPU缓存原理和缓存一致性问题

    说起Java中的多线程,就不得不说volatile关键词volatile关键词执行修饰变量和实例变量,不能修饰方法参数,局部变量和实例常量. volatile是Java提供的一种轻量级的同步机制,在并 ...

  10. java 线程由浅入深_Java多线程:由浅入深看synchronized的底层实现原理

    Java多线程:由浅入深看synchronized的底层实现原理-1.jpg (91.72 KB, 下载次数: 0) 2018-9-21 03:55 上传 前言 前俩篇文章,我们聊了聊线程/进程的概念 ...

最新文章

  1. 详解js中typeof、instanceof与constructor
  2. tcp 三次握手与四次挥手_TCP三次握手与四次挥手详解
  3. Linux入门笔记——cat、sort、uniq、wc、head、tail、tee
  4. 如何使用jmeter进行并发登录测试
  5. leetcode 移动零
  6. Linux学习总结(49)——应当竭力避免在系统中运行的 Linux 命令
  7. Js 通过点击改变css样式
  8. 嵌入式操作系统内核原理和开发(cpu的那些事)
  9. asp.net数据绑定之Eval和Bind 和等区别
  10. python迭代器_Python迭代器
  11. PageHelper.startPage 分页的坑
  12. 英语基础语法(九)-被动语态
  13. ENSP:配置静态路由表,实现不同VLAN间的通信
  14. APP、PC客户端抓包、小程序\公众号
  15. excel表格内容拆分_3个动图,教你学会如何让excel表格自动拆分,学会它,小白变大神...
  16. 英文Assignment写作段落重要性讲解
  17. gitee上传大小超过100M文件
  18. linux内核级调用时间delay函数,及常用文件头
  19. 大数据算法 chap-2 亚线性算法
  20. 因BIOS设定导致GPU无法使用问题

热门文章

  1. [ javascript ] 司徒正美的fadeOut-fadeIn效果!
  2. Roslyn 使用 Target 替换占位符方式生成 nuget 打包
  3. 【教程】MFC到Delphi的皮肤移植
  4. JAVA 事务回滚方法调用非事务回滚方法
  5. linux如何进入redis客户端,如何在linux下安装redis及客户端的连接
  6. 控制萤石云摄像头转头
  7. 小程序 微信统计表格_用微信快速收集自定义报名统计,这款小程序做到了
  8. 矩阵L2,1范数及矩阵L2,p范数的求导
  9. Win10改Win7图片查看器|Win10新增加Windows照片查看器
  10. 小米笔记本bios版本大全_RedmiBook 14笔记本评测:初来乍到却熟路轻辙