synchronized使用详解

 

synchronized详解

 

synchronized详解

1修饰类方法,锁定的是整个类
1.1同一类的不同对象,调用同一个静态同步方法,会等待锁释放

SynchronizedStatic静态同步方法

import java.util.Calendar;

public class SynchronizedStatic {
	
	public synchronized static void testThreadA(){
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("testThreadA"+Calendar.getInstance().getTimeInMillis());
	}
}

TestThreadA 线程类

public class TestThreadA extends Thread{
	SynchronizedStatic ss;
	public TestThreadA(SynchronizedStatic ss){
		this.ss = ss;
	}
	public void run(){
		ss.testThreadA();
	}
}

测试类

public class TestSyn {
	public static void main(String[] args) {
		SynchronizedStatic ss = new SynchronizedStatic();
		TestThreadA testThreadA1 = new TestThreadA(ss);
		TestThreadA testThreadA2 = new TestThreadA(ss);
		testThreadA1.start();
		testThreadA2.start();
	}
}

运行结果
testThreadA1550243750022
testThreadA1550243751043
(关于结果相差不止1秒,是我自己电脑配置不够好)

1.2同一类的不同对象,调用不同一个静态同步方法,会等待锁释放
增加一个TestThreadB ,同TestThreadA


public class TestThreadB extends Thread{
	SynchronizedStatic ss;
	public TestThreadB(SynchronizedStatic ss){
		this.ss = ss;
	}
	public void run(){
		ss.testThreadB();;
	}
}

增加一个testThreadB方法

public class SynchronizedStatic {
	
	public synchronized static void testThreadA(){
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("testThreadA"+Calendar.getInstance().getTimeInMillis());
	}
	public synchronized static void testThreadB(){
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("testThreadB"+Calendar.getInstance().getTimeInMillis());
	}
}

主程序

public class TestSyn {
	public static void main(String[] args) {
		SynchronizedStatic ss = new SynchronizedStatic();
		TestThreadA testThreadA1 = new TestThreadA(ss);
		TestThreadA testThreadA2 = new TestThreadA(ss);
		TestThreadB testThreadB1 = new TestThreadB(ss);
		testThreadA1.start();
		testThreadB1.start();
		testThreadA2.start();
	}
}

运行结果
testThreadA1550244372429
testThreadB1550244373454
testThreadA1550244374454

1.3同一对象,一个调用静态同步方法,一个调用非同步方法,不用等待锁释放
SynchronizedStatic新增方法

public  static void testThreadC(){
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("testThreadC"+Calendar.getInstance().getTimeInMillis());
	}

TestThreadC


public class TestThreadC extends Thread{
	SynchronizedStatic ss;
	public TestThreadC(SynchronizedStatic ss){
		this.ss = ss;
	}
	public void run(){
		ss.testThreadC();;
	}
}

public class TestSyn {
	public static void main(String[] args) {
		SynchronizedStatic ss = new SynchronizedStatic();
		TestThreadA testThreadA1 = new TestThreadA(ss);
		TestThreadA testThreadA2 = new TestThreadA(ss);
		TestThreadB testThreadB1 = new TestThreadB(ss);
		TestThreadC testThreadC1 = new TestThreadC(ss);
		testThreadA1.start();
		testThreadC1.start();
		testThreadB1.start();
		testThreadA2.start();
	}
}

运行结果
testThreadA1550244857145
testThreadC1550244857145
testThreadB1550244858165
testThreadA1550244859166

2修饰普通方法,锁定的是对象
2.1一个对象调用同一同步方法会等待锁释放
SynchronizedStatic 增加2个同步方法

public class SynchronizedStatic {
	
	
	public synchronized  void testThreadD(){
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("testThreadD"+Calendar.getInstance().getTimeInMillis());
	}
	
	public synchronized  void testThreadE(){
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("testThreadE"+Calendar.getInstance().getTimeInMillis());
	}
}

增加线程类TestThreadD ,(TestThreadE代码一样,不贴了 )


public class TestThreadD extends Thread{
	SynchronizedStatic ss;
	public TestThreadD(SynchronizedStatic ss){
		this.ss = ss;
	}
	public void run(){
		ss.testThreadD();;
	}
}

测试代码


public class TestSyn {
	public static void main(String[] args) {
		SynchronizedStatic ss = new SynchronizedStatic();
//		TestThreadA testThreadA1 = new TestThreadA(ss);
//		TestThreadA testThreadA2 = new TestThreadA(ss);
//		TestThreadB testThreadB1 = new TestThreadB(ss);
//		TestThreadC testThreadC1 = new TestThreadC(ss);
//		testThreadA1.start();
//		testThreadC1.start();
//		testThreadB1.start();
//		testThreadA2.start();
		TestThreadD testThreadA1 = new TestThreadD(ss);
		TestThreadD testThreadA2 = new TestThreadD(ss);
		testThreadA1.start();
		testThreadA2.start();
		
	}
}

运行结果
testThreadD1550245315866
testThreadD1550245316884
2.2一个对象调用不同同步方法会等待锁释放

public class TestSyn {
	public static void main(String[] args) {
		SynchronizedStatic ss = new SynchronizedStatic();
//		TestThreadA testThreadA1 = new TestThreadA(ss);
//		TestThreadA testThreadA2 = new TestThreadA(ss);
//		TestThreadB testThreadB1 = new TestThreadB(ss);
//		TestThreadC testThreadC1 = new TestThreadC(ss);
//		testThreadA1.start();
//		testThreadC1.start();
//		testThreadB1.start();
//		testThreadA2.start();
		TestThreadD testThreadD1 = new TestThreadD(ss);
		TestThreadD testThreadD2 = new TestThreadD(ss);
		TestThreadE testThreadE1 = new TestThreadE(ss);
		testThreadD1.start();
		testThreadE1.start();
		testThreadD2.start();
		
	}
}

运行结果
testThreadD1550245435370
testThreadE1550245436388
testThreadD1550245437389
2.3同一对象,一个调用同步方法,另一方法调用非同步方法不需要等待释放锁

public class SynchronizedStatic {
	public   void testThreadF(){
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("testThreadF"+Calendar.getInstance().getTimeInMillis());
	}
		TestThreadD testThreadD1 = new TestThreadD(ss);
		TestThreadD testThreadD2 = new TestThreadD(ss);
		TestThreadE testThreadE1 = new TestThreadE(ss);
		TestThreadF testThreadF1 = new TestThreadF(ss);
		testThreadD1.start();
		testThreadF1.start();
		testThreadE1.start();
		testThreadD2.start();

结果
testThreadF1550245592359
testThreadD1550245592359
testThreadE1550245593380
testThreadD1550245594381

3修饰代码块,锁定的也是对象
3.1当锁定是this,锁的是当前对象,与修饰的同步方法一样,会等待锁释放

public void testThreadG(){
		synchronized(this){
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println("testThreadG"+Calendar.getInstance().getTimeInMillis());
		}
	}

public class TestThreadG extends Thread{
	SynchronizedStatic ss;
	public TestThreadG(SynchronizedStatic ss){
		this.ss = ss;
	}
	public void run(){
		ss.testThreadG();;
	}
}

测试类

TestThreadG testThreadG = new TestThreadG(ss);
		TestThreadD testThreadD1 = new TestThreadD(ss);
		testThreadD1.start();
		testThreadG.start();

结果
testThreadG1550246232928
testThreadD1550246233945
3.2当锁定是其他对象,不用等待锁释放


	public void testThreadH(){
		synchronized("abc"){
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println("testThreadH"+Calendar.getInstance().getTimeInMillis());
		}
	}

测试代码

	TestThreadG testThreadG = new TestThreadG(ss);
		TestThreadD testThreadD1 = new TestThreadD(ss);
		TestThreadH testThreadH = new TestThreadH(ss);
		testThreadD1.start();
		testThreadH.start();
		testThreadG.start();

结果
testThreadH1550246385014
testThreadD1550246385014
testThreadG1550246386034

总结:synchronized修饰的是静态方法,那锁定的就是这个类。修饰的是非静态方法,锁定为对象。修饰代码块,锁定的是也是对象。一个对象只有一把锁。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值