深刻理解Java中的同步静态方法和synchronized(class)代码块的类锁

一.回顾学习内容
html

 在前面几篇博客中我咱们已经理解了synchronized对象锁、对象锁的重入、synchronized方法块、synchronized非本对象的代码块,web

 连接:https://www.cnblogs.com/SAM-CJM/category/1314992.html多线程

 咱们来总结一下,上面几篇讲到内容:并发

 1.建立线程类的两个方式:继承Thread类和实现Runable接口。异步

 2.了解了Thread类的几个基本构造器。ide

 3.启动多线程时要使用start方法,不要直接调用run方法。post

 4.几个多线程中经常使用的方法。学习

 5.解决一个共享资源被多个线程调用时采用了synchronized同步化一个对象的方法。this

 6.一个线程能够在进入一个同步化的方法时再去进入这个对象的另一个同步化方法,这个就是对象锁的重入。url

 7.为了提升程序的执行效率,咱们能够不去直接同步一个方法,直接同步这个方法中有关共享数据的部分,其余部分就是异步执行的。

 8.上一篇讲到了使用synchronized同步一个不是本对象的代码块

二.导入问题

咱们到如今使用的synchronized方法同步的都是非静态的方法也就是给一个对象上来一把对象锁,那么咱们去给一个静态方法会有什么效果呢?

三.同步将静态方法、同步类资源

其实在Java中给一个静态方法上锁就是给一个类上锁,由于类也能够是一个共享资源。

代码以下:

public class SynClass {//这个类为共享资源
    
    //这个静态方法没有被同步
    public static void fun() throws InterruptedException {
        System.out.println("**************begin**************");
        Thread.sleep(4000);
        System.out.println("**************end**************");
    }

    public static void main(String[] args) {
       ThreadA t1=new ThreadA();
       ThreadA t2=new ThreadA();
       t1.start();
       t2.start();
    }
}
class ThreadA extends Thread {//建立线程
    @Override
    public void run(){
        try {
            SynClass.fun();//调用静态方法
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

结果就是出现了线程不一样步:

修改代码以下:

    //这个静态方法被同步
   synchronized public static void fun() throws InterruptedException {
        System.out.println("**************begin**************");
        Thread.sleep(4000);
        System.out.println("**************end**************");
    }

结果被同步:

说明类也能够是共享资源,同步静态方法也是在同步类资源。

四.类锁和对象锁的认识

 假如咱们有两把锁一把是类锁,一把是对象锁,那么会出现什么状况呢?

 代码以下:

public class SynClassObject {
    //建立一个同步的静态的方法
    public synchronized static void static_fun(){//类锁
        System.out.println("**********静态方法begin*********");
        System.out.println("**********静态方法end***********");
    }
    //建立同步的非静态方法
    public synchronized void notStatic_fun(){//对象锁
        System.out.println("***********非静态方法begin*************");
        System.out.println("***********非静态方法end***************");
    }

    public static void main(String[] args) {
        new SynClassObjectThread1().start();
        new SynClassObjectThread2().start();
    }
}

class SynClassObjectThread1 extends Thread{//这个线程类调用的是同步化的静态方法
    @Override
    public void run(){
        SynClassObject.static_fun();
    }
}

class SynClassObjectThread2 extends Thread{//这个线程类是调用非静态方法
    private SynClassObject synClassObject =new SynClassObject();
    @Override
    public void run(){
        synClassObject.notStatic_fun();
    }
}

 

 结果入下: 明显他是不一样步的,由于对象锁和类锁是两把不一样的锁。

 一样的道理对于同步静态代码块,也是对类资源实现了一个同步。

 

***************************往期博客纠错******************************

在此要感谢@用户注册了一次老哥,帮助指出了深刻理解Java并发synchronized同步化的代码块不是this对象时的操做中的错误,这一篇文章只是为了说明synchronized关键字同步的是对象而不是方法,我举的列子的确有失偏颇,本人水平有限,若有错误请你们斧正。

 ************************************************************************

相关文章
相关标签/搜索