不啰嗦,我们直接开始!
代码:
public class SynchronizedObjectMethod implements Runnable { static SynchronizedObjectMethod instance = new SynchronizedObjectMethod(); @Override public void run() { method(); } public synchronized void method() { System.out.println("对象锁的方法修饰符形式,我叫:" + Thread.currentThread().getName()); try { System.out.println(Thread.currentThread().getName() + " 休眠3秒"); Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "运行结束"); } public static void main(String[] args) { //两个线程访问一个对象的同步方法,对象为instance实例 Thread t1 = new Thread(instance); Thread t2 = new Thread(instance); t1.start(); t2.start(); while (t1.isAlive() || t2.isAlive()) { } System.out.println("fininshed"); } }
运行结果:
对象锁的方法修饰符形式,我叫:Thread-0 Thread-0 休眠3秒 Thread-0运行结束 对象锁的方法修饰符形式,我叫:Thread-1 Thread-1 休眠3秒 Thread-1运行结束 fininshed
解析:需要争抢同一把锁this,所以顺序执行。
代码:
public class SynchronizedTwoThreadToTwoObject implements Runnable { static SynchronizedTwoThreadToTwoObject instance1 = new SynchronizedTwoThreadToTwoObject(); static SynchronizedTwoThreadToTwoObject instance2 = new SynchronizedTwoThreadToTwoObject(); @Override public void run() { // 当前对象作为锁 synchronized (this) { System.out.println("我是对象锁的代码块形式,我叫" + Thread.currentThread().getName()); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "运行结束"); } } public static void main(String[] args) { //两个线程访问的是两个对象的同步方法,两个对象一个为instance1,另一个为instance2 Thread t1 = new Thread(instance1); Thread t2 = new Thread(instance2); t1.start(); t2.start(); while (t1.isAlive() || t2.isAlive()) { } System.out.println("fininshed"); } }
运行结果:
我是对象锁的代码块形式,我叫Thread-0 我是对象锁的代码块形式,我叫Thread-1 Thread-1运行结束 Thread-0运行结束 fininshed
解析:并行处理,不受干扰,锁的实例不是同一个。
代码:
public class SynchronizedClassStatic implements Runnable { static SynchronizedClassStatic instance1=new SynchronizedClassStatic(); static SynchronizedClassStatic instance2=new SynchronizedClassStatic(); @Override public void run() { method(); } public static synchronized void method(){ System.out.println("我是类锁的一种形式,我叫"+Thread.currentThread().getName()); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"线程结束"); } public static void main(String[] args){ //两个线程访问synchronized的静态方法 Thread t1=new Thread(instance1); Thread t2=new Thread(instance2); t1.start(); t2.start(); while (t1.isAlive()||t2.isAlive()){ } System.out.println("fininshed"); } }
运行结果:
我是类锁的一种形式,我叫Thread-0 Thread-0线程结束 我是类锁的一种形式,我叫Thread-1 Thread-1线程结束 fininshed
解析:对应的锁是同一把,一个一个的顺序执行。
代码:
public class SynchronizedYesOrNo implements Runnable { static SynchronizedYesOrNo instance=new SynchronizedYesOrNo(); public static void main(String[] args) { Thread th1=new Thread(instance); Thread th2=new Thread(instance); th1.start(); th2.start(); while(th1.isAlive()||th2.isAlive()){ } System.out.println("finished"); } @Override public void run() { if(Thread.currentThread().getName().equals("Thread-0")){ method1(); }else{ method2(); } } public synchronized void method1(){ System.out.println("我是加了同步的方法"+Thread.currentThread().getName()); try { Thread.sleep(3000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"结束"); } public synchronized static void method2(){ System.out.println("我是没加了同步的方法"+Thread.currentThread().getName()); try { Thread.sleep(3000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"结束"); } }
运行结果:
我是加了同步的方法Thread-0 我是没加了同步的方法Thread-1 Thread-0结束 Thread-1结束 finished
解析:同步方法不会出现并发问题,非同步方法不会受到影响,出现并发问题。
代码:
public class SynchronizedDifferentMethod implements Runnable { static SynchronizedDifferentMethod instance=new SynchronizedDifferentMethod(); @Override public void run() { if(Thread.currentThread().getName().equals("Thread-0")){ method1(); }else { method2(); } } public synchronized void method1(){ System.out.println("我是加锁的方法"+Thread.currentThread().getName()); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"线程执行结束"); } public synchronized void method2(){ System.out.println("我也是加锁的方法"+Thread.currentThread().getName()+"线程执行结束"); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"线程执行结束"); } public static void main(String[] args) throws InterruptedException{ Thread t1=new Thread(instance); Thread t2=new Thread(instance); t1.start(); t2.start(); while (t1.isAlive()||t2.isAlive()){} System.out.println("fininshed"); } }
运行结果:
我是加锁的方法Thread-0 Thread-0线程执行结束 我也是加锁的方法Thread-1线程执行结束 Thread-1线程执行结束 fininshed
解析:拿到的是this锁,所以还是会受影响,串行执行。
代码:
public class SynchronizedStaticAndNormal implements Runnable { static SynchronizedStaticAndNormal instance=new SynchronizedStaticAndNormal(); @Override public void run() { if(Thread.currentThread().getName().equals("Thread-0")){ method1(); }else { method2(); } } public synchronized static void method1(){ System.out.println("我是加锁的静态方法1 "+Thread.currentThread().getName()); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"线程执行结束"); } public synchronized void method2(){ System.out.println("我是加锁的非静态方法2 "+Thread.currentThread().getName()); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"线程执行结束"); } public static void main(String[] args) throws InterruptedException{ Thread t1=new Thread(instance); Thread t2=new Thread(instance); t1.start(); t2.start(); while (t1.isAlive()||t2.isAlive()){} System.out.println("fininshed"); } }
运行结果:
我是加锁的静态方法1 Thread-0 我是加锁的非静态方法2 Thread-1 Thread-1线程执行结束 Thread-0线程执行结束 fininshed
解析:method1锁的是.class对象,method2锁的是this对象,锁不一样,没有冲突,并行执行。
代码:
public class SynchronizedException implements Runnable { static SynchronizedException instance = new SynchronizedException(); @Override public void run() { if (Thread.currentThread().getName().equals("Thread-0")) { method1(); } else { method2(); } } public synchronized void method1() { /* // 抛出Exception System.out.println("我是加锁的静态方法1" + Thread.currentThread().getName()); try { Thread.sleep(3000); //异常抛出后,JVM会自动帮你释放锁,不需要自己手动释放锁。 throw new Exception(); } catch (InterruptedException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "线程执行结束"); */ // 抛出RuntimeException System.out.println("我是加锁的静态方法1" + Thread.currentThread().getName()); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } //异常抛出后,JVM会自动帮你释放锁,不需要自己手动释放锁。 throw new RuntimeException(); // System.out.println(Thread.currentThread().getName() + "线程执行结束"); } public synchronized void method2() { System.out.println("我也是加锁的非静态方法2" + Thread.currentThread().getName()); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "线程执行结束"); } public static void main(String[] args) throws InterruptedException { Thread t1 = new Thread(instance); Thread t2 = new Thread(instance); t1.start(); t2.start(); while (t1.isAlive() || t2.isAlive()) { } System.out.println("fininshed"); } }
运行结果:
我是加锁的静态方法1Thread-0 Exception in thread "Thread-0" java.lang.RuntimeException at com.interview.javabasic.thread.a0914.SynchronizedException.method1(SynchronizedException.java:50) at com.interview.javabasic.thread.a0914.SynchronizedException.run(SynchronizedException.java:16) at java.lang.Thread.run(Thread.java:748) 我也是加锁的非静态方法2Thread-1 Thread-1线程执行结束 fininshed
解析:方法抛出异常后,会释放锁。
参考文章:
- (Synchronized)多线程访问同步方法的七种具体情况
- Java 多线程访问同步方法的七种情况
不啰嗦,文章结束,建议三连!