《java 多线程编程核心技术》读书笔记三(补充内容)

本文深入探讨了Java中synchronized关键字的使用方式及其对方法同步的影响。通过实例对比静态方法与实例方法的同步特性,揭示了不同场景下锁的实现机制。

在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这种方法)时,同步功能失效

故 第一种写法针对的是类,第二种写法针对的是对象

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值