一.关键字synchronized可以运用在静态方法上,如果这样写,那就是对当前的*.java文件对应的Class类进行持锁。
而非静态方法是给对象上锁,本质是不一样的。
二.验证案例
1)案例一:区分静态方法和非静态案例:
package org.zhq.test;
import java.util.ArrayList;
import java.util.List;
/**
* @author 作者 hq.zheng:
* @version 创建时间:2018-6-13 下午1:52:21
* 类说明
*/
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 static void printB(){
try {
System.out.println("线程名称为:"+Thread.currentThread().getName()+"在"+System.currentTimeMillis()+"进入printB");
System.out.println("线程名称为:"+Thread.currentThread().getName()+"在"+System.currentTimeMillis()+"离开printB");
} catch (Exception e) {
e.printStackTrace();
}
}
synchronized public void printC(){
try {
System.out.println("线程名称为:"+Thread.currentThread().getName()+"在"+System.currentTimeMillis()+"进入printC");
System.out.println("线程名称为:"+Thread.currentThread().getName()+"在"+System.currentTimeMillis()+"离开printC");
} catch (Exception e) {
e.printStackTrace();
}
}
}
package org.zhq.test;
/**
* @author 作者 hq.zheng:
* @version 创建时间:2018-6-13 上午11:33:08
* 类说明
*/
public class ThreadA extends Thread {
private Service service;
public ThreadA( Service service){
super();
this.service=service;
}
@Override
synchronized public void run() {
service.printA();
}
}
package org.zhq.test;
/**
* @author 作者 hq.zheng:
* @version 创建时间:2018-6-13 上午11:33:36
* 类说明
*/
public class ThreadB extends Thread {
private Service service;
public ThreadB( Service service){
super();
this.service=service;
}
@Override
synchronized public void run() {
service.printB();
}
}
package org.zhq.test;
/**
* @author 作者 hq.zheng:
* @version 创建时间:2018-6-14 上午9:03:32
* 类说明
*/
public class ThreadC extends Thread{
private Service service;
public ThreadC( Service service){
super();
this.service=service;
}
@Override
synchronized public void run() {
service.printC();
}
}
package org.zhq.test;
/**
* @author 作者 hq.zheng:
* @version 创建时间:2018-6-11 下午3:02:47
* 类说明
*/
public class Run {
public static void main(String[] args) throws InterruptedException {
Service service=new Service();
ThreadA a=new ThreadA(service);
a.setName("A");
a.start();
ThreadB b=new ThreadB(service);
b.setName("B");
b.start();
ThreadC c=new ThreadC(service);
c.setName("C");
c.start();
}
}
结果:A和C异步的原因是持有不同的锁,一个时对象锁,一个是class锁,而Class锁可以对类的所有对象实例起作用。
2)案例二:静态方法对所有的实例起作用:
package org.zhq.test;
/**
* @author 作者 hq.zheng:
* @version 创建时间:2018-6-11 下午3:02:47
* 类说明
*/
public class Run {
public static void main(String[] args) throws InterruptedException {
Service service_1=new Service();
Service service_2=new Service();
ThreadA a=new ThreadA(service_1);
a.setName("A");
a.start();
ThreadB b=new ThreadB(service_2);
b.setName("B");
b.start();
}
}
结果:虽然不是同一对象,但是同步锁同样起作用。
3)案例三:synchronized(class)代码块对所有的实例起作用:
修改service代码
package org.zhq.test;
import java.util.ArrayList;
import java.util.List;
/**
* @author 作者 hq.zheng:
* @version 创建时间:2018-6-13 下午1:52:21
* 类说明
*/
public class Service {
public static void printA(){
synchronized (Service.class) {
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();
}
}
}
public static void printB(){
synchronized (Service.class) {
try {
System.out.println("线程名称为:"+Thread.currentThread().getName()+"在"+System.currentTimeMillis()+"进入printB");
System.out.println("线程名称为:"+Thread.currentThread().getName()+"在"+System.currentTimeMillis()+"离开printB");
} catch (Exception e) {
e.printStackTrace();
}
}
}
synchronized public void printC(){
try {
System.out.println("线程名称为:"+Thread.currentThread().getName()+"在"+System.currentTimeMillis()+"进入printC");
System.out.println("线程名称为:"+Thread.currentThread().getName()+"在"+System.currentTimeMillis()+"离开printC");
} catch (Exception e) {
e.printStackTrace();
}
}
}
再次运行run
package org.zhq.test;
/**
* @author 作者 hq.zheng:
* @version 创建时间:2018-6-11 下午3:02:47
* 类说明
*/
public class Run {
public static void main(String[] args) throws InterruptedException {
Service service_1=new Service();
Service service_2=new Service();
ThreadA a=new ThreadA(service_1);
a.setName("A");
a.start();
ThreadB b=new ThreadB(service_2);
b.setName("B");
b.start();
}
}
结果:跟静态方法效果一致。