静态同步synchronized方法与synchronized(class)代码块

关键字synchronized可以应用在static静态方法上,代表着对当前*.java文件对应的Class类进行持锁。

package other.thread4;

public class Service {

    public synchronized 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) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    
    public synchronized static void printB() {
        System.out.println("线程:" + Thread.currentThread().getName()
                + "在" + System.currentTimeMillis() + "进入printB");
        System.out.println("线程:" + Thread.currentThread().getName()
                + "在" + System.currentTimeMillis() + "离开printB");
    }
    
}

public class ThreadA extends Thread {
    @Override
    public void run() {
        Service.printA();
    }
}
public class ThreadB extends Thread {
    @Override
    public void run() {
        Service.printB();
    }
}
public class Test {

    public static void main(String[] args) {
        ThreadA threadA = new ThreadA();
        threadA.setName("A");
        threadA.start();
        ThreadB threadB = new ThreadB();
        threadB.setName("B");
        threadB.start();
    }

}
image.png
从运行效果来看,似乎都是同步的效果,就和将synchronized关键字加到非static方法上使用的效果是一样的。其实两者有着本质的不同,synchronized关键字加到static静态方法上是给Class类上锁,而synchronized关键字加到非static静态方法上是给对象上锁。

验证

public class Service {

    public synchronized static void printA() {
        try {
            System.out.println("线程:" + Thread.currentThread().getName()
                    + "在" + System.currentTimeMillis() + "进入printA");
            Thread.sleep(1000);
            System.out.println("线程:" + Thread.currentThread().getName()
                    + "在" + System.currentTimeMillis() + "离开printA");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    
    public synchronized void printB() {
        System.out.println("线程:" + Thread.currentThread().getName()
                + "在" + System.currentTimeMillis() + "进入printB");
        System.out.println("线程:" + Thread.currentThread().getName()
                + "在" + System.currentTimeMillis() + "离开printB");
    }
    
}

public class ThreadA extends Thread {

private Service service;

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

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

}

public class ThreadB extends Thread {
private Service service;

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

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

}

public class Test {

public static void main(String[] args) {
    Service service = new Service();
    ThreadA threadA = new ThreadA(service);
    threadA.setName("A");
    threadA.start();
    ThreadB threadB = new ThreadB(service);
    threadB.setName("B");
    threadB.start();
}

}

![image.png](https://upload-images.jianshu.io/upload_images/16792546-797b5f13d240e700.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

###异步的原因是持有不同的锁,一个是对象锁,另外一个是Class锁,而Class锁可以对类的所有对象实例起作用。

public class Service {

public synchronized static void printA() {
    try {
        System.out.println("线程:" + Thread.currentThread().getName()
                + "在" + System.currentTimeMillis() + "进入printA");
        Thread.sleep(1000);
        System.out.println("线程:" + Thread.currentThread().getName()
                + "在" + System.currentTimeMillis() + "离开printA");
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

public synchronized static void printB() {
    System.out.println("线程:" + Thread.currentThread().getName()
            + "在" + System.currentTimeMillis() + "进入printB");
    System.out.println("线程:" + Thread.currentThread().getName()
            + "在" + System.currentTimeMillis() + "离开printB");
}

}

package other.thread4;

public class ThreadA extends Thread {

private Service service;

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

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

}

package other.thread4;

public class ThreadB extends Thread {
private Service service;

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

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

}

public class Test {

public static void main(String[] args) {
    Service service = new Service();
    ThreadA threadA = new ThreadA(service);
    threadA.setName("A");
    threadA.start();
    Service service2 = new Service();
    ThreadB threadB = new ThreadB(service2);
    threadB.setName("B");
    threadB.start();
}

}


![image.png](https://upload-images.jianshu.io/upload_images/16792546-23f79793288c97df.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

同步synchronized(class)代码块的作用其实和synchronized static方法的作用一样。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。