synchronized锁

synchronized锁介绍

 synchronized是Java的一个关键字。来自官方的解释:Synchronized方法支持一种简单的策略,用于防止线程干扰和内存一致性错误:如果一个对象对多个线程可见,则对该对象变量的所有读或写操作都通过Synchronized方法完成。

synchronized锁的特性

       Synchronized保证同一时刻有且只有一条线程在操作共享数据,其他线程必须等待该线程处理完数据后再对共享数据进行操作。此时便产生了互斥锁,互斥锁的特性如下:

互斥性:即在同一时刻只允许一个线程持有某个对象锁,通过这种特性来实现多线程协调机制,这样在同一时刻只有一个线程对所需要的同步的代码块(复合操作)进行访问。互斥性也成为了操作的原子性。
可见性:必须确保在锁释放之前,对共享变量所做的修改,对于随后获得该锁的另一个线程可见(即在获得锁时应获得最新共享变量的值),否则另一个线程可能是在本地缓存的某个副本上继续操作,从而引起数据不一致。

Synchronized是最基本的互斥手段,保证同一时刻最多只有1个线程执行被Synchronized修饰的方法 / 代码,其他线程 必须等待当前线程执行完该方法 / 代码块后才能执行该方法 / 代码块。

synchronized有三种应用场景

  1. 对于普通同步方法,锁是当前实例对象。
  2. 对于静态同步方法,锁是当前类的Class对象。
  3. 对于同步方法块,锁是Synchronized括号里配置的对象。

1.synchronized方法用作对象锁时:

下面看一段测试用例,一共创建了三个类

Person类(初始状态下都不加锁)

package bingfa;
 
public class Person {
	public volatile int age;
	public String name;
 
	public void m1() {
		System.out.println("m1方法开始");
		try {
			Thread.sleep(2000);
		} catch (Exception e) {}
		System.out.println("m1方法结束");
	}
	public void m2() {
		System.out.println("m2方法开始");
		try {
			Thread.sleep(2000);
		} catch (Exception e) {}
		System.out.println("m2方法结束");
	}
	public static void m3() {
		System.out.println("m3方法开始");
		try {
			Thread.sleep(2000);
		} catch (Exception e) {}
		System.out.println("m3方法结束");
	}
 
	public static void m4() {
		System.out.println("m4方法开始");
		try {
			Thread.sleep(2000);
		} catch (Exception e) {}
		System.out.println("m4方法结束");
	}
}

ThreadTest类

package bingfa;
 
public class ThreadPlus extends Thread{
    private   Person  m;
    private int flag;
    public ThreadPlus(Person x, int w) {
        m = x;
        flag = w;
    }
    @Override
    public  void run() {
        if(flag == 1) {
            m.m1();
        }else {
            m.m2();
        }
    }
}

主方法类

package bingfa;
public class Test {
	public static void main(String[] args) throws Exception{
		Person x1 = new Person();
		Person x2 = new Person();
//====================================================
		ThreadPlus t1 = new ThreadPlus(x1,1);
		ThreadPlus t2 = new ThreadPlus(x1,2);
 
		t1.start();
		t2.start();
		//=======
		t1.join();
		t2.join();
	}
}

然后我们使用synchronized关键字分别进行测试

注意:两个线程操作的是同一个对象!

m1,m2方法都不加锁

这时m1,m2两个线程可以同时执行

m1加锁

只有一个方法加锁,不构成互斥条件,因此m1,m2两个方法也互不影响,自由执行。

m1,m2同时加锁

这是构成了互斥条件,同一时刻,m1和m2只能有一个正在执行。

2.synchronized方法用作类锁时:

修饰的static静态方法,与上面作为对象锁时类似,只有两个静态方法同时加锁,才构成互斥条件,二者不能同时执行,其余互不干扰

也就是说只有类型相同时互斥,静态和非静态之间互不干扰。

3.修饰代码块

需要注意的是,synchronized只能锁引用类型,而不能锁基本类型

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值