版权声明:版权归 爱装逼的文艺小青年所有 https://blog.csdn.net/toyota_rav4/article/details/85012800
静态同步synchronized方法
package com.demo19;
public class MyObject {
synchronized public static void a(){
try {
System.out.println("线程:" + Thread.currentThread().getName() + " 开始时间:" + System.currentTimeMillis());
Thread.sleep(3000);
System.out.println("线程:" + Thread.currentThread().getName() + " 结束时间:" + System.currentTimeMillis());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized public static void b(){
System.out.println("线程:" + Thread.currentThread().getName() + " 开始时间:" + System.currentTimeMillis());
System.out.println("线程:" + Thread.currentThread().getName() + " 结束时间:" + System.currentTimeMillis());
}
}
package com.demo19;
public class ThreadA extends Thread {
@Override
public void run() {
MyObject.a();
}
}
package com.demo19;
public class ThreadB extends Thread {
@Override
public void run() {
MyObject.b();
}
}
package com.demo19;
public class run {
public static void main(String[] args) {
ThreadA threadA = new ThreadA();
ThreadB threadB = new ThreadB();
threadA.setName("A");
threadB.setName("B");
threadA.start();
threadB.start();
}
}
运行结果:
线程:A 开始时间:1544844475598
线程:A 结束时间:1544844478598
线程:B 开始时间:1544844478598
线程:B 结束时间:1544844478598
看上去跟之前使用synchronized同步非静态方法的效果没什么区别,但本质上却是有区别的。synchronized同步静态方法,加在class上;synchronized同步非静态方法,是给对象上锁。
为了验证不是同一个锁,继续进行实验。
package com.demo19;
public class MyObject {
synchronized public static void a(){
try {
System.out.println("线程:" + Thread.currentThread().getName() + " 开始时间:" + System.currentTimeMillis());
Thread.sleep(3000);
System.out.println("线程:" + Thread.currentThread().getName() + " 结束时间:" + System.currentTimeMillis());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized public static void b(){
System.out.println("线程:" + Thread.currentThread().getName() + " 开始时间:" + System.currentTimeMillis());
System.out.println("线程:" + Thread.currentThread().getName() + " 结束时间:" + System.currentTimeMillis());
}
synchronized public void c(){
System.out.println("线程:" + Thread.currentThread().getName() + " 开始时间:" + System.currentTimeMillis());
System.out.println("线程:" + Thread.currentThread().getName() + " 结束时间:" + System.currentTimeMillis());
}
}
package com.demo19;
public class ThreadA extends Thread {
private MyObject myObject;
public ThreadA(MyObject myObject) {
this.myObject = myObject;
}
@Override
public void run() {
MyObject.a();
}
}
package com.demo19;
public class ThreadB extends Thread {
private MyObject myObject;
public ThreadB(MyObject myObject) {
this.myObject = myObject;
}
@Override
public void run() {
MyObject.b();
}
}
package com.demo19;
public class ThreadC extends Thread {
private MyObject myObject;
public ThreadC(MyObject myObject) {
this.myObject = myObject;
}
@Override
public void run(){
myObject.c();
}
}
package com.demo19;
public class run {
public static void main(String[] args) {
MyObject myObject = new MyObject();
ThreadA threadA = new ThreadA(myObject);
ThreadB threadB = new ThreadB(myObject);
ThreadC threadC = new ThreadC(myObject);
threadA.setName("A");
threadB.setName("B");
threadC.setName("C");
threadA.start();
threadB.start();
threadC.start();
}
}
运行结果:
线程:A 开始时间:1544845870678
线程:C 开始时间:1544845870679
线程:C 结束时间:1544845870679
线程:A 结束时间:1544845873678
线程:B 开始时间:1544845873678
线程:B 结束时间:1544845873678
很明显 异步,原因是持有不同的锁。一个是对象锁,一个是class锁。class锁可以对类的所有实例对象起作用!
下面对该结论进行实验:
package com.demo19;
public class MyObject {
synchronized public static void a(){
try {
System.out.println("线程:" + Thread.currentThread().getName() + " 开始时间:" + System.currentTimeMillis());
Thread.sleep(3000);
System.out.println("线程:" + Thread.currentThread().getName() + " 结束时间:" + System.currentTimeMillis());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized public static void b(){
System.out.println("线程:" + Thread.currentThread().getName() + " 开始时间:" + System.currentTimeMillis());
System.out.println("线程:" + Thread.currentThread().getName() + " 结束时间:" + System.currentTimeMillis());
}
}
package com.demo19;
public class ThreadA extends Thread {
private MyObject myObject;
public ThreadA(MyObject myObject) {
this.myObject = myObject;
}
@Override
public void run() {
MyObject.a();
}
}
package com.demo19;
public class ThreadB extends Thread {
private MyObject myObject;
public ThreadB(MyObject myObject) {
this.myObject = myObject;
}
@Override
public void run() {
MyObject.b();
}
}
package com.demo19;
public class run {
public static void main(String[] args) {
MyObject myObject1 = new MyObject();
MyObject myObject2 = new MyObject();
ThreadA threadA = new ThreadA(myObject1);
ThreadB threadB = new ThreadB(myObject2);
threadA.setName("A");
threadB.setName("B");
threadA.start();
threadB.start();
}
}
运行结果:
线程:A 开始时间:1544846287092
线程:A 结束时间:1544846290092
线程:B 开始时间:1544846290092
线程:B 结束时间:1544846290092
通过结论验证,class锁可以对类的所有对象实例起作用。
synchronized(class)同步代码块
package com.demo19;
public class MyObject {
public void a(){
synchronized (MyObject.class){
try {
System.out.println("线程:" + Thread.currentThread().getName() + " 开始时间:" + System.currentTimeMillis());
Thread.sleep(3000);
System.out.println("线程:" + Thread.currentThread().getName() + " 结束时间:" + System.currentTimeMillis());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void b(){
synchronized(MyObject.class){
System.out.println("线程:" + Thread.currentThread().getName() + " 开始时间:" + System.currentTimeMillis());
System.out.println("线程:" + Thread.currentThread().getName() + " 结束时间:" + System.currentTimeMillis());
}
}
}
package com.demo19;
public class ThreadA extends Thread {
private MyObject myObject;
public ThreadA(MyObject myObject) {
this.myObject = myObject;
}
@Override
public void run() {
myObject.a();
}
}
package com.demo19;
public class ThreadB extends Thread {
private MyObject myObject;
public ThreadB(MyObject myObject) {
this.myObject = myObject;
}
@Override
public void run() {
myObject.b();
}
}
package com.demo19;
public class run {
public static void main(String[] args) {
MyObject myObject1 = new MyObject();
MyObject myObject2 = new MyObject();
ThreadA threadA = new ThreadA(myObject1);
ThreadB threadB = new ThreadB(myObject2);
threadA.setName("A");
threadB.setName("B");
threadA.start();
threadB.start();
}
}
运行结果:
线程:A 开始时间:1544846633091
线程:A 结束时间:1544846636092
线程:B 开始时间:1544846636092
线程:B 结束时间:1544846636092
结论:synchronized(class)与同步静态方法的作用一样。