JAVA多线程之——对象锁的理解

转载自微信公众号 Java面试通关手册 ——Java多线程学习(二)synchronized关键字(1)作者:Snaiclimb

多个对象多个锁

例子:

这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

输出
这里写图片描述

代码解释:
athread.start()后,调用addI(),传入字符”a”,”a set over”后,线程a睡眠了,并未释放a的锁,bthread.start()后,可以调用addI,因为他们不是一个HasSelfPrivateNum对象,锁也不是一个锁,输出”b set over”,。。。然后a醒来继续输出。。。

synchronized取得的锁都是对象锁,而不是把一段代码或方法当做锁。如果多个线程访问的是同一个对象,哪个线程先执行带synchronized关键字的方法,则哪个线程就持有该方法,那么其他线程只能呈等待状态。如果多个线程访问的是多个对象则不一定,因为多个对象会产生多个锁。

那么我们思考一下当多个线程访问的是同一个对象中的非synchronized类型方法会是什么效果?重点内容

答案是:会异步调用非synchronized类型方法,解决办法也很简单在非synchronized类型方法前加上synchronized关键字即可。

脏读

发生脏读的情况实在读取实例变量时,此值已经被其他线程更改过。
代码
这里写图片描述

这里写图片描述
这里写图片描述
输出:
这里写图片描述

代码解释:
thread.start(),会调用setValue(“B”,”BB”)
username赋值为B,然后线程睡眠,资源交给主线程main(),主线程也睡眠,但是时间短,于是主线程先开始执行下面的语句,即g调用了getValue,此时由于thread处于休眠,只赋值了username,所以getValue是 B AA,待thread唤醒后,继续赋值,输出B BB ,问题就在于,setValue还未执行完毕的时候,主线程就访问了getValue导致了脏读,加入synchronized之后,由于锁是对象锁,即使thread在睡眠,但是并未释放对象锁,所以主线程main此时并不可以访问有sychronized的getValue!

扫描二维码关注公众号,回复: 2557182 查看本文章

问题:如果线程都不休眠,那么thread和main线程是同时运行吗,同时的话就也有可能产生和上面情况相似的脏读,涉及到多线程的本质问题,多线程是怎么运行的,同时吗?
解释:并发与并行
这里写图片描述

  • 微观角度:所有的并发处理都有排队等候,唤醒,执行等这样的步骤,在微观上他们都是序列被处理的,如果是同一时刻到达的请求(或线程)也会根据优先级的不同,而先后进入队列排队等候执行。
  • 宏观角度:多个几乎同时到达的请求(或线程)在宏观上看就像是同时在被处理。
  • 通俗点讲,并发就是只有一个CPU资源,程序(或线程)之间要竞争得到执行机会。图中的第一个阶段,在A执行的过程中B,C不会执行,因为这段时间内这个CPU资源被A竞争到了,同理,第二个阶段只有B在执行,第三个阶段只有C在执行。其实,并发过程中,A,B,C并不是同时在进行的(微观角度)。但又是同时进行的(宏观角度)。

getvalue()加上synchronized
这里写图片描述

猜你喜欢

转载自blog.csdn.net/weixin_38719347/article/details/81260480