摘要:
本文只讲解synchronized方法(同步方法)的锁的对象是谁;
synchronized:锁的对象是调用该方法的对象
static synchronized:所得对象是类.class
public class Test1 { //结果:发短信---打电话
public static void main(String[] args) throws InterruptedException {
Phone phone = new Phone();
new Thread(()->{phone.send();}).start();
TimeUnit.SECONDS.sleep(1); //主线程阻塞一秒,导致了线程1先拿到phone的锁
new Thread(()->{phone.call();}).start();
}
}
class Phone{
public synchronized void send() {
System.out.println("发短信");
}
public synchronized void call(){
System.out.println("打电话");
}
}
public class Test2 { //结果:发短信---打电话
public static void main(String[] args) throws InterruptedException {
Phone1 phone = new Phone1();
new Thread(()->{phone.send();}).start();
TimeUnit.SECONDS.sleep(1); //主线程阻塞1秒,导致线程1先拿到锁,拿到锁之后,进入阻塞,但并没有释放锁
new Thread(()->{phone.call();}).start();
}
}
class Phone1{
//锁的对象是方法的调用者,上面两个进程都是用的同一个对象,因此是同一把锁
public synchronized void send() {
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("发短信");
}
public synchronized void call(){
System.out.println("打电话");
}
}
public class Test3 { //结果:hello---发短信
public static void main(String[] args) throws InterruptedException {
Phone3 phone = new Phone3();
new Thread(()->{phone.send();}).start();
TimeUnit.SECONDS.sleep(1); //主线程阻塞1秒
new Thread(()->{phone.hello();}).start(); //hello不是同步方法,所以有没有锁都能进去
}
}
class Phone3{
//锁的对象是方法的调用者,上面两个进程都是用的同一个对象,因此是同一把锁
public synchronized void send() {
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("发短信");
}
public synchronized void call(){
System.out.println("打电话");
}
public void hello(){
System.out.println("hello");
}
}
public class Test4 { //结果:打电话---发短信
public static void main(String[] args) throws InterruptedException {
Phone4 phone1 = new Phone4();
Phone4 phone2 = new Phone4();
new Thread(()->{phone1.send();}).start();
TimeUnit.SECONDS.sleep(1); //主线程阻塞1秒,线程1拿到phone1的锁
new Thread(()->{phone2.call();}).start(); //主线程不阻塞后,线程2的锁因为是phone2的所以能进去
}
}
class Phone4{
//锁的对象是方法的调用者,上面两个进程使用的对象不同,因此锁不同
public synchronized void send() {
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("发短信");
}
public synchronized void call(){
System.out.println("打电话");
}
}
public class Test5 { //结果:发短信-打电话
public static void main(String[] args) throws InterruptedException {
Phone5 phone = new Phone5();
new Thread(()->{phone.send();}).start();
TimeUnit.SECONDS.sleep(1); //主线程阻塞1秒,导致线程1先拿到Phone5.class的锁,线程2准备进去发现上锁了,进不去
new Thread(()->{phone.call();}).start();
}
}
class Phone5{
//static synchronized的锁对象是Phone5.class
public static synchronized void send() {
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("发短信");
}
public static synchronized void call(){
System.out.println("打电话");
}
}
public class Test6 { //结果:打电话-发短信
public static void main(String[] args) throws InterruptedException {
Phone6 phone = new Phone6();
new Thread(()->{phone.send();}).start();
TimeUnit.SECONDS.sleep(1); //主线程阻塞1秒,导致线程1拿到了Phone6.class,注意是拿到了Phone6.class,而不是phone
new Thread(()->{phone.call();}).start();//主线程结束阻塞后,线程2判断phone的锁还在,能进去
}
}
class Phone6{
public static synchronized void send() {
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("发短信");
}
public synchronized void call(){
System.out.println("打电话");
}
}
public class Test7 { //结果:打电话-发短信
public static void main(String[] args) throws InterruptedException {
Phone7 phone1 = new Phone7();
Phone7 phone2 = new Phone7();
new Thread(()->{phone1.send();}).start();
TimeUnit.SECONDS.sleep(1); //主线程阻塞1秒,线程1拿到Phone7.class
new Thread(()->{phone2.call();}).start();//主线程结束阻塞,线程2拿到phone2
}
}
class Phone7{
public static synchronized void send() {
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("发短信");
}
public synchronized void call(){
System.out.println("打电话");
}
}