本文内容部分引自《Java多线程编程核心技术》,感谢作者!!!
代码地址:https://github.com/xianzhixianzhixian/thread.git
结论:当一个类的同一个实例被多个线程使用时,这些线程持有的是这个实例的对象锁。一个线程在执行该类中synchronized修饰的方法时,其它线程可以调用该类中非synchronized修饰的方法;如果其它线程要调用该类中synchronized修饰的方法则需等待,也就是同步。
书本截图:
MyObject.java
package thread.synchronize.lock;
/**
* 验证多个线程调用一个类的同一个实例时synchronized修饰的方法和非synchronized修饰的方法的同步性
* @author: xianzhixianzhixian
* @date: 2018-12-13 22:09
*/
public class MyObject {
synchronized public void methodA(){
try {
System.out.println("begin synchronized methodA threadName="+ Thread.currentThread().getName());
Thread.sleep(1000);
System.out.println("end");
} catch (Exception e) {
e.printStackTrace();
}
}
public void methodB(){
try {
System.out.println("begin asynchronized methodB threadName="+ Thread.currentThread().getName());
Thread.sleep(1000);
System.out.println("end");
} catch (Exception e) {
e.printStackTrace();
}
}
synchronized public void methodC(){
try {
System.out.println("begin synchronized methodC threadName="+ Thread.currentThread().getName());
Thread.sleep(1000);
System.out.println("end");
} catch (Exception e) {
e.printStackTrace();
}
}
}
ThreadA.java
package thread.synchronize.lock;
/**
* @author: xianzhixianzhixian
* @date: 2018-12-13 22:13
*/
public class ThreadA extends Thread {
private MyObject myObject;
public ThreadA(MyObject object){
this.myObject = object;
}
@Override
public void run() {
super.run();
myObject.methodA();
}
}
ThreadAA.java
package thread.synchronize.lock;
/**
* @author: xianzhixianzhixian
* @date: 2018-12-13 22:13
*/
public class ThreadAA extends Thread {
private MyObject myObject;
public ThreadAA(MyObject object){
this.myObject = object;
}
@Override
public void run() {
super.run();
myObject.methodA();
}
}
ThreadB.java
package thread.synchronize.lock;
/**
* @author: xianzhixianzhixian
* @date: 2018-12-13 22:13
*/
public class ThreadB extends Thread {
private MyObject myObject;
public ThreadB(MyObject object){
this.myObject = object;
}
@Override
public void run() {
super.run();
myObject.methodB();
}
}
ThreadC.java
package thread.synchronize.lock;
/**
* @author: xianzhixianzhixian
* @date: 2018-12-13 22:13
*/
public class ThreadC extends Thread {
private MyObject myObject;
public ThreadC(MyObject object){
this.myObject = object;
}
@Override
public void run() {
super.run();
myObject.methodC();
}
}
先看两个线程一个调用synchronized修饰的方法,另一个调用非synchronized修饰的方法
结果是两个方法可以同时被调用
Run.java
package thread.synchronize.lock;
/**
* @author: xianzhixianzhixian
* @date: 2018-12-13 22:16
*/
public class Run {
public static void main(String[] args) {
MyObject object = new MyObject();
ThreadA threadA = new ThreadA(object);
ThreadB threadB = new ThreadB(object);
threadA.start();
threadB.start();
}
}
运行结果
再看三个线程同时运行,其中两个线程调用synchronized修饰的同一个方法,另一个线程调用synchronized修饰的另一个方法
结果是同步的,只有一个线程执行结束后(释放该对象的锁之后),另一个线程才能继续执行synchronized修饰的方法,否则就只能等待锁被释放。
Run.java
package thread.synchronize.lock;
/**
* @author: xianzhixianzhixian
* @date: 2018-12-13 22:16
*/
public class Run {
public static void main(String[] args) {
MyObject object = new MyObject();
ThreadA threadA = new ThreadA(object);
ThreadAA threadAA = new ThreadAA(object);
//ThreadB threadB = new ThreadB(object);
ThreadC threadC = new ThreadC(object);
threadA.start();
threadAA.start();
//threadB.start();
threadC.start();
}
}
运行结果