使用synchronized对并发性的影响

1 前言

  • 非静态方法的同步锁是当前对象(this)(对象锁)
  • 静态方法的同步锁是当前类的字节码(类锁)
  • 不同的锁之间能并发

2 同一对象内

本节主类与资源类如下:

class Resorce{ //资源
	static int x=0;
	static int y=0;
}

public class Main {
	public static void main(String[] args) {
		Operate op=new Operate();
		Thread t1=new Thread() {
			public void run() {
				op.fun1();
			}
		};
		Thread t2=new Thread() {
			public void run() {
				op.fun2();
			}
		};
		t1.start();
		t2.start();
	}
}

2.1 两个非static方法,一个被synchronized修饰,一个未被修饰,能否并发?(能并发)

(本例中两个方法访问同一资源,能并发;若访问不同资源,也能并发)

class Operate{
	void fun1() {
		for(int i=0;i<3;i++) {
			Resorce.x++;
			for(int j=0;j<1000;j++); //延时
			System.out.println("t1-uux:"+Resorce.x);
		}
	}
	
	synchronized void fun2() {
		for(int i=0;i<3;i++) {
			Resorce.x++;
			for(int j=0;j<1000;j++); //延时
			System.out.println("t2-sux:"+Resorce.x);
		}
	}
}

运行结果:

t1-sux:2
t2-uux:2
t2-uux:4
t1-sux:3
t1-sux:6
t2-uux:5

sux:被synchronized修饰,未被static修饰,资源为x;

uux:未被synchronized修饰,未被static修饰,资源为x。

2.2 两个非static方法,都被synchronized修饰,能否并发?(不能并发)

(本例中两个方法访问不同资源,不能并发;若访问同一资源,也不能并发)

class Operate{
	synchronized void fun1() {
		for(int i=0;i<3;i++) {
			Resorce.x++;
			for(int j=0;j<1000;j++); //延时
			System.out.println("t1-sux:"+Resorce.x);
		}
	}
	
	synchronized void fun2() {
		for(int i=0;i<3;i++) {
			Resorce.y++;
			for(int j=0;j<1000;j++); //延时
			System.out.println("t2-suy:"+Resorce.y);
		}
	}
}

运行结果:

t1-sux:1
t1-sux:2
t1-sux:3
t2-suy:1
t2-suy:2
t2-suy:3

sux:被synchronized修饰,未被static修饰,资源为x;

suy:被synchronized修饰,未被static修饰,资源为y。

2.3 两个synchronized方法,一个被static修饰,一个未被修饰,能否并发?(能并发)

(本例中两个方法访问同一资源,能并发;若访问不同资源,也能并发)

class Operate{
	synchronized void fun1() {
		for(int i=0;i<3;i++) {
			Resorce.x++;
			for(int j=0;j<1000;j++); //延时
			System.out.println("t1-sux:"+Resorce.x);
		}
	}
	
	synchronized static void fun2() {
		for(int i=0;i<3;i++) {
			Resorce.x++;
			for(int j=0;j<1000;j++); //延时
			System.out.println("t2-ssx:"+Resorce.x);
		}
	}
}

运行结果:

t1-ssx:2
t1-ssx:3
t2-sux:2
t1-ssx:4
t2-sux:5
t2-sux:6

ssx:被synchronized修饰,被static修饰,资源为x;

sux:被synchronized修饰,未被static修饰,资源为x。

2.4 两个static方法,都被synchronized修饰,能否并发?(不能并发)

(本例中两个方法访问不同资源,不能并发;若访问同一资源,也不能并发)

class Operate{
	synchronized static void fun1() {
		for(int i=0;i<3;i++) {
			Resorce.x++;
			for(int j=0;j<1000;j++); //延时
			System.out.println("t1-ssx:"+Resorce.x);
		}
	}
	
	synchronized static void fun2() {
		for(int i=0;i<3;i++) {
			Resorce.y++;
			for(int j=0;j<1000;j++); //延时
			System.out.println("t2-ssy:"+Resorce.y);
		}
	}
}

运行结果:

t1-ssx:1
t1-ssx:2
t1-ssx:3
t2-ssy:1
t2-ssy:2
t2-ssy:3

ssx:被synchronized修饰,被static修饰,资源为x;

ssy:被synchronized修饰,被static修饰,资源为y。

3 不同对象间

针对第2节中的两种不能并发的情况进行讨论,主类和资源类如下:

class Resorce{ //临界资源
	static int x=0;
	static int y=0;
}

public class Main {
	public static void main(String[] args) {
		Operate op1=new Operate();
		Operate op2=new Operate();
		Thread t1=new Thread() {
			public void run() {
				op1.fun1();
			}
		};
		Thread t2=new Thread() {
			public void run() {
				op2.fun2();
			}
		};
		t1.start();
		t2.start();
	}
}

3.1 两个非static方法,都被synchronized修饰,能否并发?(能并发)

(本例中两个方法访问同一资源,能并发;若访问不同资源,也能并发)

class Operate{
	synchronized void fun1() {
		for(int i=0;i<3;i++) {
			Resorce.x++;
			for(int j=0;j<1000;j++); //延时
			System.out.println("t1-sux:"+Resorce.x);
		}
	}

	synchronized void fun2() {
		for(int i=0;i<3;i++) {
			Resorce.x++;
			for(int j=0;j<1000;j++); //延时
			System.out.println("t2-sux:"+Resorce.x);
		}
	}
}

运行结果:

t2-sux:2
t1-sux:2
t1-sux:4
t1-sux:5
t2-sux:3
t2-sux:6

sux:被synchronized修饰,未被static修饰,资源为x。

3.2 两个static方法,都被synchronized修饰,能否并发?(不能并发)

(本例中两个方法访问不同资源,不能并发;若访问同一资源,也不能并发)

class Operate{
	synchronized static void fun1() {
		for(int i=0;i<3;i++) {
			Resorce.x++;
			for(int j=0;j<1000;j++); //延时
			System.out.println("t1-ssx:"+Resorce.x);
		}
	}
	
	synchronized static void fun2() {
		for(int i=0;i<3;i++) {
			Resorce.y++;
			for(int j=0;j<1000;j++); //延时
			System.out.println("t2-ssy:"+Resorce.y);
		}
	}
}

运行结果:

t1-ssx:1
t1-ssx:2
t1-ssx:3
t2-ssy:1
t2-ssy:2
t2-ssy:3

ssx:被synchronized修饰,被static修饰,资源为x;

ssy:被synchronized修饰,被static修饰,资源为y。

4 注意事项

这里的资源不是临界资源,临界资源由信号量来控制其访问。

​ 声明:本文转自使用synchronized对并发性的影响

posted @   little_fat_sheep  阅读(74)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
点击右上角即可分享
微信分享提示