Java多线程问题--静态同步synchronized方法和synchronized(class)代码块

本文内容部分引自《Java多线程编程核心技术》,感谢作者!!!

代码地址:https://github.com/xianzhixianzhixian/thread.git

1、关键字synchronized还可以用在static静态方法上,如果这样写是对当前的*.java文件对应的Class类进行持锁。

2、同步synchronized(Class)代码块的作用和sunchronized static方法的作用一样,都是对当前的*.java文件对应的Class类进行持锁,都是Class锁。

3、Class锁和对象锁不一样,对象锁是锁定当前对象,Class锁是对类的所有对象实例起作用。

4、synchronized(Class)、sunchronized static和synchronized(object)是不同的锁,Class锁锁定的是Class类所有的对象实例,synchronized(object)锁定的是Class的某一个对象。

5、当多个线程同时占用Class锁和对象锁时,占有Class锁的线程和占有对象锁的线程是异步运行的。

写程序进行验证

Service.java

package thread.synchronize.static_;

/**
 * 验证synchronized static和synchronized(Class)是对类的所有对象起作用(上锁)
 * @author: xianzhixianzhixian
 * @date: 2018-12-18 19:35
 */
public class Service {

    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 (Exception e) {
            e.printStackTrace();
        }
    }

    synchronized public void printB(){
        try {
            System.out.println("线程名称为:"+Thread.currentThread().getName()+"在"+System.currentTimeMillis()+"进入同步方法printB()");
            Thread.sleep(3000);
            System.out.println("线程名称为:"+Thread.currentThread().getName()+"在"+System.currentTimeMillis()+"离开同步方法printB()");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void printC(){
        synchronized (Service.class){
            try {
                System.out.println("线程名称为:"+Thread.currentThread().getName()+"在"+System.currentTimeMillis()+"进入Class同步块printB()");
                Thread.sleep(3000);
                System.out.println("线程名称为:"+Thread.currentThread().getName()+"在"+System.currentTimeMillis()+"离开Class同步块printB()");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    synchronized public static void printD(){
        try {
            System.out.println("线程名称为:"+Thread.currentThread().getName()+"在"+System.currentTimeMillis()+"进入静态同步方法printD()");
            Thread.sleep(3000);
            System.out.println("线程名称为:"+Thread.currentThread().getName()+"在"+System.currentTimeMillis()+"离开静态同步方法printD()");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void printE(){
        synchronized (Service.class){
            try {
                System.out.println("线程名称为:"+Thread.currentThread().getName()+"在"+System.currentTimeMillis()+"进入Class同步块printB()");
                Thread.sleep(3000);
                System.out.println("线程名称为:"+Thread.currentThread().getName()+"在"+System.currentTimeMillis()+"离开Class同步块printB()");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

ThreadA.java

package thread.synchronize.static_;

/**
 * @author: xianzhixianzhixian
 * @date: 2018-12-18 19:41
 */
public class ThreadA extends Thread {

    private Service service;

    public ThreadA(Service service) {
        this.service = service;
    }

    @Override
    public void run() {
        super.run();
        service.printA();
    }
}

ThreadB.java

package thread.synchronize.static_;

/**
 * @author: xianzhixianzhixian
 * @date: 2018-12-18 19:41
 */
public class ThreadB extends Thread {

    private Service service;

    public ThreadB(Service service) {
        this.service = service;
    }

    @Override
    public void run() {
        super.run();
        service.printB();
    }
}

ThreadC.java

package thread.synchronize.static_;

/**
 * @author: xianzhixianzhixian
 * @date: 2018-12-18 19:41
 */
public class ThreadC extends Thread {

    private Service service;

    public ThreadC(Service service) {
        this.service = service;
    }

    @Override
    public void run() {
        super.run();
        service.printC();
    }
}

ThreadD.java

package thread.synchronize.static_;

/**
 * @author: xianzhixianzhixian
 * @date: 2018-12-18 19:41
 */
public class ThreadD extends Thread {

    private Service service;

    public ThreadD(Service service) {
        this.service = service;
    }

    @Override
    public void run() {
        super.run();
        service.printD();
    }
}

ThreadE.java

package thread.synchronize.static_;

/**
 * @author: xianzhixianzhixian
 * @date: 2018-12-18 19:41
 */
public class ThreadE extends Thread {

    private Service service;

    public ThreadE(Service service) {
        this.service = service;
    }

    @Override
    public void run() {
        super.run();
        service.printE();
    }
}

Run.java

package thread.synchronize.static_;

/**
 * @author: xianzhixianzhixian
 * @date: 2018-12-18 19:41
 */
public class Run {

    public static void main(String[] args) {
        Service service = new Service();
        Service service1 = new Service();

        ThreadA threadA = new ThreadA(service);
        threadA.setName("a");
        ThreadB threadB = new ThreadB(service);
        threadB.setName("b");
        ThreadC threadC = new ThreadC(service1);
        threadC.setName("c");
        ThreadD threadD = new ThreadD(service1);
        threadD.setName("d");
        ThreadE threadE = new ThreadE(service);
        threadE.setName("e");

        threadA.start();
        threadB.start();
        threadC.start();
        threadD.start();
        threadE.start();
    }
}

运行结果:其中线程a、c、d、e是同步运行的,其持有的都是Class锁。而线程b持有的是对象锁,和其它线程异步运行。这也验证了Class锁和对象锁是两种不同类型的锁,而synchronized static和synchronized(Class)是对类的所有对象实例起作用的。

Java多线程问题--静态同步synchronized方法和synchronized(class)代码块_第1张图片

你可能感兴趣的:(Java,多线程)