加深对synchronized的理解
-
两个线程调用同一个对象的两个同步方法
/** * * 被synchronized修饰的方法,锁的对象是方法的调用者。因为两个方法的调用者是同一个, * 所以两个方法用的是同一个锁,先调用方法的先执行。 * one * two */ public class SynchronizedTest1 { public static void main(String[] args) { Number number = new Number(); new Thread(number::getOne).start(); new Thread(number::getTwo).start(); } static class Number { public synchronized void getOne() { System.out.println("one"); } public synchronized void getTwo() { System.out.println("two"); } } } -
新增Thread.sleep()给某个方法
/** * 被synchronized修饰的方法,锁的对象是方法的调用者。因为两个方法的调用者是同一个, * 所以两个方法用的是同一个锁,先调用方法的先执行, * 第二个方法只有在第一个方法执行完释放锁之后才能执行。 * sleep方法,让线程沉睡,但不会让线程释放锁。 * one * two */ public class SynchronizedTest2 { public static void main(String[] args) { Number number = new Number(); new Thread(number::getOne).start(); new Thread(number::getTwo).start(); } static class Number { public synchronized void getOne() { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("one"); } public synchronized void getTwo() { System.out.println("two"); } } } -
新增一个线程调用新增的一个普通的方法
/** * 新增的方法没有被synchronized修饰,不是同步方法,不受锁的影响,所以不需要等待。 * 其他线程共用一把锁,所以还需要等待。 * three * one * two */ public class SynchronizedTest2 { public static void main(String[] args) { Number number = new Number(); new Thread(number::getOne).start(); new Thread(number::getTwo).start(); new Thread(number::getThree).start(); } static class Number { public synchronized void getOne() { try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("one"); } public synchronized void getTwo() { System.out.println("two"); } public void getThree() { System.out.println("three"); } } } -
两个线程调用两个对象的同步方法,其中一个方法有Thread.sleep
/** * 被synchronized修饰的方法,锁的对象是方法的调用者。 * 因为用了两个对象调用各自的方法,所以两个方法的调用者不是同一个, * 所以两个方法用的不是同一个锁,后调用的方法,不需要等待先调用的方法,先调用的需要睡眠,所以会晚点结束。 * two * one */ public class SynchronizedTest4 { public static void main(String[] args) { Number number1 = new Number(); Number number2 = new Number(); new Thread(number1::getOne).start(); new Thread(number2::getTwo).start(); } static class Number { public synchronized void getOne() { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("one"); } public synchronized void getTwo() { System.out.println("two"); } } } -
将有Thread.sleep的方法设置为static方法,并且让两个线程用同一个对象调用两个方法
/** * 被synchronized和static修饰的方法,锁的对象是类的class对象。 * 仅仅被synchronized修饰的方法,锁的对象是方法的调用者。 * 所以两个方法用的不是同一个锁,后调用的方法不需要等待先调用的方法, * two * one */ public class SynchronizedTest5 { public static void main(String[] args) { Number number = new Number(); new Thread(Number::getOne).start(); new Thread(number::getTwo).start(); } static class Number { public static synchronized void getOne() { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("one"); } public synchronized void getTwo() { System.out.println("two"); } } } -
都设置为static方法,两个线程去调用两个方法
/** * 被synchronized和static修饰的方法,锁的对象是类的class对象。 * 因为两个同步方法都被static修饰了,所以两个方法用的是同一个锁,后调用的方法需要等待先调用的方法 * one * two */ public class SynchronizedTest6 { public static void main(String[] args) { new Thread(Number::getOne).start(); new Thread(Number::getTwo).start(); } static class Number { public static synchronized void getOne() { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("one"); } public static synchronized void getTwo() { System.out.println("two"); } } }

789

被折叠的 条评论
为什么被折叠?



