1 synchronized 关键字的4种用法

写在前面: 虽然平时自己有做笔记的习惯,但都保存在本地。但随着笔记量的增多,自己打开笔记的习惯渐渐消失了。所以试试博客,一是好找笔记,二是能相互交流。一举两得。感谢关注我博客的朋友,这会督促我不断的学习、进步。高并发这块是观看马士兵老师的教程做的随堂笔记。感谢马老师!

注意:共享资源读写的时候才涉及到线程同步。

多线程同步:即限制某个资源在同一时刻只能被一个线程访问。

1.1 第1种写法(o)

/**
 * synchronized关键字
 * 对某个对象加锁
 * @author mashibing
 */

package yxxy.c_001;

public class T {
	
	private int count = 10;
	private Object o = new Object();
	
	public void m() {
		synchronized(o) { //任何线程要执行下面的代码,必须先拿到o的锁
			count--;
			System.out.println(Thread.currentThread().getName() + " count = " + count);
		}
	}
}

解说: 要执行这段代码,先去执行这个对象的锁。 注意:这个对象锁画出来的堆内存new出来的对象,而不是引用 也就是说在真正申请锁的时候,这个锁的信息是记录在堆内存对象中。 如果o要是指向别的对象,你这个锁的对象就变了。 只要有一个线程拿到锁,其他线程就拿不到锁。—> 这称为互斥锁

也就是把o给锁定了!

1.2 第2种写法(this)

刚才这把锁是我们自己new出来的,但是这样每次new一个不干别的,专门当锁的对象实在是太麻烦了。 以下为简便写法: new 一个T出来,指向自身。把自身的对象锁定。【锁定自身再执行代码】

注意:synchronized锁定的是一个对象,而不是代码块。

/**
 * synchronized关键字
 * 对某个对象加锁
 * [@author](https://my.oschina.net/arthor) mashibing
 */

package yxxy.c_002;

public class T {
	
	private int count = 10;
	
	public void m() {
		synchronized(this) { //任何线程要执行下面的代码,必须先拿到this的锁
			count--;
			System.out.println(Thread.currentThread().getName() + " count = " + count);
		}
	}
}

1.3 第3种写法(写在方法声明上)

如果一段代码在开始的时候就要synchronized(this)。到结束的时候才释放这把锁。那有一个简便的写法。

直接写在方法的声明上:

package yxxy.c_003;

public class T {

   private int count = 10;
   
   public synchronized void m() { //等同于在方法的代码执行时要synchronized(this)
      count--;
      System.out.println(Thread.currentThread().getName() + " count = " + count);
   }

}

1.4 synchronized 用在静态方法上

相当于锁定的是T.class【锁定的是当前Class类对象】

/**
 * synchronized关键字
 * 对某个对象加锁
 * @author mashibing
 */

package yxxy.c_004;

public class T {

	private static int count = 10;
	
	public synchronized static void m() { //这里等同于synchronized(yxxy.c_004.T.class)
		count--;
		System.out.println(Thread.currentThread().getName() + " count = " + count);
	}
	
	//相当于是下面这种写法
	public static void mm() {
		synchronized(T.class) { //考虑一下这里写synchronized(this)是否可以?
            //t.class 是Class里面的对象 [反射知识]
			count --;
		}
	}

}

由于静态的时候是没有this可以锁定,静态的属性和方法是不需要new对象来访问的。所以就没有this引用的存在。

1.5 分析程序的输出

发现问题: 5个线程访问的count都是同一个。

在没打印之前另外2个线程又减了2下。所以变成7了。

这就是线程同步的问题。 加锁即可解决。

总结:synchronized 是原子操作,不可分

转载于:https://my.oschina.net/u/4131327/blog/3048115

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值