在java中根据是否有static关键字修饰,方法可分为 类方法、实例方法
synchronized public static void methodA(){}
synchronized public void methodB(){}
那这两种方法在加上synchronized关键字后其同步效果是否一致呢?
接下来我们通过代码来验证下
public class Services {
//锁的是类,同一个类有效
synchronized public static void methodA(){
System.out.println("======methodA start========"+Thread.currentThread().getName());
try{
Thread.sleep(2000);
}catch (Exception e){
e.printStackTrace();
}
System.out.println("======methodA end ========"+Thread.currentThread().getName());
}
//锁的是对象,同一个对象有效
synchronized public void methodB(){
System.out.println("======methodB start========"+Thread.currentThread().getName());
try{
Thread.sleep(2000);
}catch (Exception e){
e.printStackTrace();
}
System.out.println("======methodB end ========"+Thread.currentThread().getName());
}
}
public class MyThreadA extends Thread{
private Services services;
public MyThreadA(Services services) {
this.services = services;
}
@Override
public void run() {
super.run();
// services.methodA();
services.methodB();
}
}
public class MyThreadB extends Thread {
private Services services;
public MyThreadB(Services services) {
this.services = services;
}
@Override
public void run() {
super.run();
// services.methodA();
services.methodB();
}
}
测试一:
public class Run {
public static void main(String[] args){
Services servicesA = new Services();
// Services servicesB = new Services();
MyThreadA myThreadA = new MyThreadA(servicesA);
MyThreadB myThreadB = new MyThreadB(servicesA);
myThreadA.start();
myThreadB.start();
}
}
两个线程访问同一个对像的同一个实例方法,输出内容为同步打印
测试二: 修改Run.java中的代码如下
public class Run {
public static void main(String[] args){
Services servicesA = new Services();
Services servicesB = new Services();
MyThreadA myThreadA = new MyThreadA(servicesA);
MyThreadB myThreadB = new MyThreadB(servicesB);
myThreadA.start();
myThreadB.start();
}
}
两个线程访问同一个类的两个实例对象中相同的实例方法,即A线程访问的是servicesA.methodB(),B线程访问的是servicesB.methodB(),输出内容为异步打印
测试三: 在测试二的基础上修改MyThreadA、MyThreadB,屏蔽对methodB()的调用,放开对methodA()的调用,即线程A访问的是servicesA.methodA(),B线程访问的是servicesB.methodA(),输出内容为同步打印
结论:
synchronized public static void methodA(){}
在多个线程分别访问同一个类的多个对象(都调用methodA这种方法)时,同步功能依然生效
synchronized public void methodB(){}
在多个线程分别访问同一个类的多个对象(都调用methodB这种方法)时,同步功能失效
故 第一种写法针对的是类,第二种写法针对的是对象
本文深入探讨了Java中synchronized关键字的使用方式及其对方法同步的影响。通过实例对比静态方法与实例方法的同步特性,揭示了不同场景下锁的实现机制。

259

被折叠的 条评论
为什么被折叠?



