彻底搞懂对象并发访问(五)

总览


多线程+synchronized+static(例子)

Service类

public class Service {
	//注意添加了static关键字
    synchronized public static void PrintA() {
        try {
            System.out.println("线程名称为:" + Thread.currentThread().getName() +
                    "在" + System.currentTimeMillis() + "进入printA");
            Thread.sleep(3000);
            System.out.println("线程名称为:" + Thread.currentThread().getName() +
                    "在" + System.currentTimeMillis() + "离开printA");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    
	//注意添加了static关键字
    synchronized public static void printB() {
        System.out.println("线程名称为:" + Thread.currentThread().getName() +
                "在" + System.currentTimeMillis() + "进入printB");
        System.out.println("线程名称为:" + Thread.currentThread().getName() +
                "在" + System.currentTimeMillis() + "离开printB");
    }
}

ThreadA.java

public class ThreadA extends Thread {
    @Override
    public void run() {
        //注意这里直接用类名调用,而不是对象
        Service.PrintA();
    }
}

ThreadB.java

public class ThreadB extends Thread {
    @Override
    public void run() {
        //注意这里直接用类名调用,而不是对象
        Service.printB();
    }
}

Run.java

public class Run {
    public static void main(String[] args) {

        ThreadA a = new ThreadA();
        a.setName("A");
        a.start();

        ThreadB b = new ThreadB();
        b.setName("B");
        b.start();
    }
}

运行结果

在这里插入图片描述


原理图(类锁)

在这里插入图片描述


总结

  • 可以看到结果是同步的效果,好像也没什么特别之处,但是注意这里并没有用对象!!!,而是直接用了类名调用的方法,sychronized+static得到的是类锁,所以当Service.PrintA()执行完毕后,才会去执行Service.PrintB()

  • 下一篇在此例子的基础上,将用类名调用方法改成用对象调用,也就是多线程+单对象+synchronized+static,就会发现是异步效果,因为此时要看类锁而不是对象锁。

猜你喜欢

转载自blog.csdn.net/weixin_37418246/article/details/89212158