synchronized关键字修饰方法或者代码块,保证在同一时刻最多只有一个线程来访问代码块。有几种情况:
1>当两个并发线程同时访问同一个对象中的synchronized代码块时,同一时刻只能由一个线程执行,另一个线程必须等当前线程结束后才可以继续执行该同步代码块。
2>当一个线程执行object的synchronized代码块时,另一个线程可以执行对象中的非synchronized代码块。
3>当一个线程执行synchronized代码块时,其他线程对object的其他synchronized同步代码块的执行也会被阻塞的。也就是说当一个线程执行对象的synchronized代码块时,获取了对象的锁,其他的线程对object中synchronized同步方法的执行会被阻塞。
下面分别通过几个例子演示下这种情况:
1>两个并发线程同时访问一个对象中synchronized代码块
package com.example.springbootDemo.service.synchronizDemo; public class MyThread implements Runnable { @Override public void run() { synchronized(this) { for (int i = 0; i < 5; i++) { System.out.println(Thread.currentThread().getName() + " synchronized loop " + i); } } } public static void main(String[] args) { MyThread myThread = new MyThread(); Thread thread1 = new Thread(myThread,"A"); Thread thread2 = new Thread(myThread,"B"); thread1.start(); thread2.start(); } }
执行结果:
A synchronized loop 0
A synchronized loop 1
A synchronized loop 2
A synchronized loop 3
A synchronized loop 4
B synchronized loop 0
B synchronized loop 1
B synchronized loop 2
B synchronized loop 3
B synchronized loop 4
2>当一个线程访问object的同步代码块时,另一个线程可以访问object的非synchronized方法
package com.example.springbootDemo.service.synchronizDemo; public class Thread2 { public void mythod1() { synchronized (this) { int i = 5; while (i-- > 0) { System.out.println(Thread.currentThread().getName() + " : " + i); try { Thread.sleep(500); } catch (InterruptedException ie) { } } } } public void mythod2() { int i = 5; while (i-- > 0) { System.out.println(Thread.currentThread().getName() + " : " + i); try { Thread.sleep(500); } catch (InterruptedException e) { } } } public static void main(String[] args) { final Thread2 myt2 = new Thread2(); Thread t1 = new Thread(new Runnable() { @Override public void run() { myt2.mythod1(); } }); Thread t2 = new Thread(new Runnable() { @Override public void run() { myt2.mythod2(); } }); t1.start(); t2.start(); } }
执行结果
Thread-0 : 4
Thread-1 : 4
Thread-1 : 3
Thread-0 : 3
Thread-0 : 2
Thread-1 : 2
Thread-0 : 1
Thread-0 : 0
Thread-1 : 1
Thread-1 : 0
3>当一个线程执行object的同步代码块,其他线程对object的其他同步代码块的执行也会被阻塞
package com.example.springbootDemo.service.synchronizDemo; public class Thread2 { public void mythod1() { synchronized (this) { int i = 5; while (i-- > 0) { System.out.println(Thread.currentThread().getName() + " : " + i); try { Thread.sleep(500); } catch (InterruptedException ie) { } } } } public synchronized void mythod2() { int i = 5; while (i-- > 0) { System.out.println(Thread.currentThread().getName() + " : " + i); try { Thread.sleep(500); } catch (InterruptedException e) { } } } public static void main(String[] args) { final Thread2 myt2 = new Thread2(); Thread t1 = new Thread(new Runnable() { @Override public void run() { myt2.mythod1(); } }); Thread t2 = new Thread(new Runnable() { @Override public void run() { myt2.mythod2(); } }); t1.start(); t2.start(); } }
执行结果:
Thread-0 : 4
Thread-0 : 3
Thread-0 : 2
Thread-0 : 1
Thread-0 : 0
Thread-1 : 4
Thread-1 : 3
Thread-1 : 2
Thread-1 : 1
Thread-1 : 0