public class Condition2 implements Runnable { // 创建两个不同的对象 static Condition2 instance1 = new Condition2(); static Condition2 instance2 = new Condition2(); @Override public void run() { method(); } private synchronized void method() { System.out.println("线程名:" Thread.currentThread().getName() ",运行开始"); try { Thread.sleep(4000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("线程:" Thread.currentThread().getName() ",运行结束"); } public static void main(String[] args) { Thread thread1 = new Thread(instance1); Thread thread2 = new Thread(instance2); thread1.start(); thread2.start(); while (thread1.isAlive() || thread2.isAlive()) { } System.out.println("测试结束"); } }
线程名:Thread-0,运行开始 线程名:Thread-1,运行开始 线程:Thread-0,运行结束 线程:Thread-1,运行结束 测试结束
public class Condition4 implements Runnable { static Condition4 instance = new Condition4(); @Override public void run() { //两个线程访问同步方法和非同步方法 if (Thread.currentThread().getName().equals("Thread-0")) { //线程0,执行同步方法method0() method0(); } if (Thread.currentThread().getName().equals("Thread-1")) { //线程1,执行非同步方法method1() method1(); } } // 同步方法 private synchronized void method0() { System.out.println("线程名:" Thread.currentThread().getName() ",同步方法,运行开始"); try { Thread.sleep(4000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("线程:" Thread.currentThread().getName() ",同步方法,运行结束"); } // 普通方法 private void method1() { System.out.println("线程名:" Thread.currentThread().getName() ",普通方法,运行开始"); try { Thread.sleep(4000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("线程:" Thread.currentThread().getName() ",普通方法,运行结束"); } public static void main(String[] args) { Thread thread1 = new Thread(instance); Thread thread2 = new Thread(instance); thread1.start(); thread2.start(); while (thread1.isAlive() || thread2.isAlive()) { } System.out.println("测试结束"); } }
线程名:Thread-0,同步方法,运行开始 线程名:Thread-1,普通方法,运行开始 线程:Thread-0,同步方法,运行结束 线程:Thread-1,普通方法,运行结束 测试结束
public class Condition8 implements Runnable { static Condition8 instance = new Condition8(); @Override public void run() { if (Thread.currentThread().getName().equals("Thread-0")) { //直接调用普通方法 method2(); } else { // 先调用同步方法,在同步方法内调用普通方法 method1(); } } // 同步方法 private static synchronized void method1() { System.out.println("线程名:" Thread.currentThread().getName() ",同步方法,运行开始"); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("线程:" Thread.currentThread().getName() ",同步方法,运行结束,开始调用普通方法"); method2(); } // 普通方法 private static void method2() { System.out.println("线程名:" Thread.currentThread().getName() ",普通方法,运行开始"); try { Thread.sleep(4000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("线程:" Thread.currentThread().getName() ",普通方法,运行结束"); } public static void main(String[] args) { // 此线程直接调用普通方法 Thread thread0 = new Thread(instance); // 这两个线程直接调用同步方法 Thread thread1 = new Thread(instance); Thread thread2 = new Thread(instance); thread0.start(); thread1.start(); thread2.start(); while (thread0.isAlive() || thread1.isAlive() || thread2.isAlive()) { } System.out.println("测试结束"); } }
线程名:Thread-0,普通方法,运行开始 线程名:Thread-1,同步方法,运行开始 线程:Thread-1,同步方法,运行结束,开始调用普通方法 线程名:Thread-1,普通方法,运行开始 线程:Thread-0,普通方法,运行结束 线程:Thread-1,普通方法,运行结束 线程名:Thread-2,同步方法,运行开始 线程:Thread-2,同步方法,运行结束,开始调用普通方法 线程名:Thread-2,普通方法,运行开始 线程:Thread-2,普通方法,运行结束 测试结束
public class Condition5 implements Runnable { static Condition5 instance = new Condition5(); @Override public void run() { if (Thread.currentThread().getName().equals("Thread-0")) { //线程0,执行同步方法method0() method0(); } if (Thread.currentThread().getName().equals("Thread-1")) { //线程1,执行同步方法method1() method1(); } } private synchronized void method0() { System.out.println("线程名:" Thread.currentThread().getName() ",同步方法0,运行开始"); try { Thread.sleep(4000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("线程:" Thread.currentThread().getName() ",同步方法0,运行结束"); } private synchronized void method1() { System.out.println("线程名:" Thread.currentThread().getName() ",同步方法1,运行开始"); try { Thread.sleep(4000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("线程:" Thread.currentThread().getName() ",同步方法1,运行结束"); } //运行结果:串行 public static void main(String[] args) { Thread thread1 = new Thread(instance); Thread thread2 = new Thread(instance); thread1.start(); thread2.start(); while (thread1.isAlive() || thread2.isAlive()) { } System.out.println("测试结束"); } }
线程名:Thread-1,同步方法1,运行开始 线程:Thread-1,同步方法1,运行结束 线程名:Thread-0,同步方法0,运行开始 线程:Thread-0,同步方法0,运行结束 测试结束
public class Condition6 implements Runnable { static Condition6 instance = new Condition6(); @Override public void run() { if (Thread.currentThread().getName().equals("Thread-0")) { //线程0,执行静态同步方法method0() method0(); } if (Thread.currentThread().getName().equals("Thread-1")) { //线程1,执行非静态同步方法method1() method1(); } } // 重点:用static synchronized 修饰的方法,属于类锁,锁对象为(*.class)对象。 private static synchronized void method0() { System.out.println("线程名:" Thread.currentThread().getName() ",静态同步方法0,运行开始"); try { Thread.sleep(4000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("线程:" Thread.currentThread().getName() ",静态同步方法0,运行结束"); } // 重点:synchronized 修饰的方法,属于方法锁,锁对象为(this)对象。 private synchronized void method1() { System.out.println("线程名:" Thread.currentThread().getName() ",非静态同步方法1,运行开始"); try { Thread.sleep(4000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("线程:" Thread.currentThread().getName() ",非静态同步方法1,运行结束"); } //运行结果:并行 public static void main(String[] args) { //问题原因: 线程1的锁是类锁(*.class)对象,线程2的锁是方法锁(this)对象,两个线程的锁不一样,自然不会互相影响,所以会并行执行。 Thread thread1 = new Thread(instance); Thread thread2 = new Thread(instance); thread1.start(); thread2.start(); while (thread1.isAlive() || thread2.isAlive()) { } System.out.println("测试结束"); }
线程名:Thread-0,静态同步方法0,运行开始 线程名:Thread-1,非静态同步方法1,运行开始 线程:Thread-1,非静态同步方法1,运行结束 线程:Thread-0,静态同步方法0,运行结束 测试结束
public class Condition7 implements Runnable { private static Condition7 instance = new Condition7(); @Override public void run() { if (Thread.currentThread().getName().equals("Thread-0")) { //线程0,执行抛异常方法method0() method0(); } if (Thread.currentThread().getName().equals("Thread-1")) { //线程1,执行正常方法method1() method1(); } } private synchronized void method0() { System.out.println("线程名:" Thread.currentThread().getName() ",运行开始"); try { Thread.sleep(4000); } catch (InterruptedException e) { e.printStackTrace(); } //同步方法中,当抛出异常时,JVM会自动释放锁,不需要手动释放,其他线程即可获取到该锁 System.out.println("线程名:" Thread.currentThread().getName() ",抛出异常,释放锁"); throw new RuntimeException(); } private synchronized void method1() { System.out.println("线程名:" Thread.currentThread().getName() ",运行开始"); try { Thread.sleep(4000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("线程:" Thread.currentThread().getName() ",运行结束"); } public static void main(String[] args) { Thread thread1 = new Thread(instance); Thread thread2 = new Thread(instance); thread1.start(); thread2.start(); while (thread1.isAlive() || thread2.isAlive()) { } System.out.println("测试结束"); } }
线程名:Thread-0,运行开始 线程名:Thread-0,抛出异常,释放锁 线程名:Thread-1,运行开始 Exception in thread "Thread-0" java.lang.RuntimeException at com.study.synchronize.conditions.Condition7.method0(Condition7.java:34) at com.study.synchronize.conditions.Condition7.run(Condition7.java:17) at java.lang.Thread.run(Thread.java:748) 线程:Thread-1,运行结束 测试结束