Java多线程编程核心技术--第二章 对象及变量的并发访问synchronized

本文详细探讨了Java中的线程安全问题,解释了synchronized关键字如何确保对象锁的安全,包括方法级锁、对象锁、锁重入、脏读避免以及锁的粒度控制。同时,文章对比了synchronized方法与同步代码块的不同,以及如何利用任意对象作为对象监视器实现高效同步。
摘要由CSDN通过智能技术生成

一、方法中的变量不存在非线程安全问题,永远都是线程安全的,这是方法内部的变量是私有的特性造成的。
二、多个对象多个锁

1)、关键字synchronized取得的锁都是对象锁,而不是一段代码或者方法当做锁,所以在上面的示例中,那个线程先执行带synchronized关键字的方法,那个线程就持有该方法所属对象的锁Lock,那么其他线程只能呈等待状态,前提是多个线程访问的是同一个对象。
2)、但如果多个现场访问多个对象,则JVM会创建多个锁。上面的示例就是创建了2个HasSelfPrivateNum.java类的对象,所以产生出2个锁。两个线程分别访问同一个类的两个实例的相同名称的同步方法,效果却是异步的方式运行。

三、synchronized方法和锁对象
1)、synchronized锁住的是括号里的对象,而不是代码;
2)、使用synchronized能在代码段上添加同步,就不要在整个方法上添加同步,减少锁的颗粒度;
3)、调用关键字synchronized声明的方法一定是排队运行的;
4)、只有“共享资源”的读写访问才需要同步化,如果不是共享资源,那么根本就没有同步的必要;
5)、
实验一:两个自定义线程类分别调用同一个类中不同的两个方法;
结论:A线程先持有object对象的Lock锁,B线程可以以异步的方式调用object对象中的非synchronized类型的方法;
试验二:两个自定义线程类分别调用同一个类中添加synchronized的两个方法;
结论:A线程先持有object对象的Lock锁,B线程如果在这时调用object对象中的synchronized类型的方法则需要等待,也就是同步;

四、脏读
定义:虽然在赋值时进行了同步,但在取值时,有可能出现一些意想不到的意外,这种情况就是脏读;

五、synchronized锁重入
1)、定义:使用synchronized时,当一个线程得到一个对象的锁后,再次请求此对象锁时,是可以再次得到该对象的锁的。
2)、当存在父子类继承关系时,子类是完全可以通过“可重入锁”调用父类的同步方法的。

六、同步不可继承
七、synchronized同步语句块
1)、和synchronized方法一样,synchronized(this)代码块也是锁定当前对象的
2)、synchronized方法是对当前对象进行加锁,而synchronized(this)代码块是对某一对象进行加锁;
3)、当一个线程访问object的一个synchronized同步代码块时,另一个线程仍然可以访问该object对象中的非synchronized(this)同步代码,通过缩小synchronized的颗粒度来加快程序的运行效率;
4)、当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对同一个object中所有其他synchronized(this)同步代码块的访问将被阻塞,这说明synchronized使用的“对象监视器”是一个;

八、将任意对象作为对象监视器
一)、多个线程调用同一个对象中的不同名称的synchronized同步方法或synchronized(this)同步代码块时,调用的效果就是顺序执行,也就是同步的阻塞的。
二)、这说明synchronized同步方法或synchronized(this)同步代码分别有两种作用:
1、synchronized同步方法
1)、对其他synchronized同步方法或synchronized(this)同步代码块调用呈现阻塞状态;
2)、同一时间只有一个线程可以执行synchronized同步方法中的代码;
2、synchronized(this)同步代码块
1)、对其他synchronized同步方法或synchronized(this)同步代码块调用呈现阻塞状态;
2)、同一时间只有一个线程可以执行synchronized(this)同步代码块中的代码;

3、java中还支持对“任意对象”作为“对象监视器”来实现同步的功能,这个“任意对象”大多数是实例变量及方法的参数,使用格式为synchronized(非this对象x);
4、synchronized(非this对象x)同步代码块
1)、在多个线程持有“对象监视器”胃痛一个对象的前提下,同一时间只有一个线程可以执行synchronized(非this对象x)同步代码块中的代码;
2)、当持有“对象监视器”为同一个对象的前提下,同一时间只有一个线程可以执行synchronized(非this对象x)同步代码块中的代码;
5、synchronized(非this对象x)的有点
如果在一个类中有很多个synchronized方法,这时虽然能实现同步,但会收到阻塞,所以影响运行效率;但如果使用同步代码块非this对象,则synchronized(非this对象x)代码块中的程序与同步方法是异步的,不与其他锁this同步方法争抢this锁,则可大大提高运行效率;
6、使用synchronized(非this对象x)同步代码块格式进行同步操作时,对象监视器必须是同一个对象;

九、数据类型String的常量池特性

public static void pring (String stringParam){
	synchronized (StringParam){
		while(true){
			System.out.println();
			}
		}

定义两个线程执行 结果线程A一直运行的死循环,因为String的两个值都是“AA”,两个线程持有相同的锁,所以,造成线程B不能执行。 这就是String常量池所带来的问题,因此在大多数情况下,同步synchronized代码都不使用String作为锁对象,而改用其他,比如new Object()实例化一个Object对象,但它并不放入缓存中。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值