第一条:当一个线程访问某对象的synchronized方法或者synchronized代码块时,其他线程对该对象的该synchronized方法或者synchronized代码块的访问将被阻塞。
public class MoreThread {public static void main(String[] args) {Piao piao = new Piao();Thread t1 = new Thread(piao);Thread t2 = new Thread(piao);Thread t3 = new Thread(piao);t1.start();t2.start();t3.start();}
}class Piao implements Runnable {@Overridepublic void run() {/*synchronized(this) {*/for (int i = 0; i < 10; i++) {try {Thread.sleep(100);System.out.println(Thread.currentThread().getName() + " 卖票:ticket " + i);} catch (InterruptedException e) {e.printStackTrace();}}/*}*/}
}
没有加上synchronized:
Thread-1 卖票:ticket 0
Thread-0 卖票:ticket 0
Thread-2 卖票:ticket 0
Thread-1 卖票:ticket 1
Thread-0 卖票:ticket 1
Thread-2 卖票:ticket 1
Thread-1 卖票:ticket 2
Thread-0 卖票:ticket 2
Thread-2 卖票:ticket 2
Thread-1 卖票:ticket 3
Thread-0 卖票:ticket 3
Thread-2 卖票:ticket 3
Thread-0 卖票:ticket 4
Thread-2 卖票:ticket 4
Thread-1 卖票:ticket 4
Thread-2 卖票:ticket 5
Thread-0 卖票:ticket 5
Thread-1 卖票:ticket 5
Thread-1 卖票:ticket 6
Thread-2 卖票:ticket 6
Thread-0 卖票:ticket 6
Thread-1 卖票:ticket 7
Thread-0 卖票:ticket 7
Thread-2 卖票:ticket 7
Thread-1 卖票:ticket 8
Thread-0 卖票:ticket 8
Thread-2 卖票:ticket 8
Thread-1 卖票:ticket 9
Thread-2 卖票:ticket 9
Thread-0 卖票:ticket 9
加上synchronized:这个代码块要等一个线程访问完成之后,另一个线程才能访问。
Thread-1 卖票:ticket 0
Thread-1 卖票:ticket 1
Thread-1 卖票:ticket 2
Thread-1 卖票:ticket 3
Thread-1 卖票:ticket 4
Thread-1 卖票:ticket 5
Thread-1 卖票:ticket 6
Thread-1 卖票:ticket 7
Thread-1 卖票:ticket 8
Thread-1 卖票:ticket 9
Thread-0 卖票:ticket 0
Thread-0 卖票:ticket 1
Thread-0 卖票:ticket 2
Thread-0 卖票:ticket 3
Thread-0 卖票:ticket 4
Thread-0 卖票:ticket 5
Thread-0 卖票:ticket 6
Thread-0 卖票:ticket 7
Thread-0 卖票:ticket 8
Thread-0 卖票:ticket 9
Thread-2 卖票:ticket 0
Thread-2 卖票:ticket 1
Thread-2 卖票:ticket 2
Thread-2 卖票:ticket 3
Thread-2 卖票:ticket 4
Thread-2 卖票:ticket 5
Thread-2 卖票:ticket 6
Thread-2 卖票:ticket 7
Thread-2 卖票:ticket 8
Thread-2 卖票:ticket 9
第二条:当一个线程访问某对象的synchronized方法或者synchronized代码块时,其他线程仍然可以访问该对象的非同步代码块。
1 public class MoreThread { 2 public static void main(String[] args) { 3 TestSynchronized t = new TestSynchronized(); 4 Thread t1 = new Thread(() -> t.SynMethod()); 5 Thread t2 = new Thread(() -> t.NoSynMethod()); 6 7 t1.start(); 8 t2.start(); 9 } 10 11 } 12 class TestSynchronized { 13 14 public void SynMethod() { 15 synchronized (this) { 16 try { 17 for (int i = 0; i < 5; i++) { 18 Thread.sleep(1000); // 休眠100ms 19 System.out.println(Thread.currentThread().getName() + " synMethod loop " + i); 20 } 21 } catch (InterruptedException ie) { 22 } 23 } 24 } 25 26 public void NoSynMethod() { 27 synchronized (this) { 28 try { 29 for (int i = 0; i < 5; i++) { 30 Thread.sleep(1000); // 休眠100ms 31 System.out.println(Thread.currentThread().getName() + " synMethod loop " + i); 32 } 33 } catch (InterruptedException e) { 34 e.printStackTrace(); 35 } 36 } 37 }
当线程 t1去调用含有synchronized()的时候,会获取到对象的同步锁(每一个对象有且只有一个同步锁)。此时线程 t2 可以去调用没有synchronized修饰的代码块。不会发生阻塞。执行结果会交叉执行
1 Thread-0 synMethod loop 0 2 Thread-1 synMethod loop 0 3 Thread-0 synMethod loop 1 4 Thread-1 synMethod loop 1 5 Thread-0 synMethod loop 2 6 Thread-1 synMethod loop 2 7 Thread-1 synMethod loop 3 8 Thread-0 synMethod loop 3 9 Thread-1 synMethod loop 4 10 Thread-0 synMethod loop 4 11 12 Process finished with exit code 0
如果给方法中加上synchroniezd(this) 那么线程t2在执行的时候会发生阻塞。会等一个线程执行完后,释放锁后,另一线程才会运行
1 Thread-1 synMethod loop 0 2 Thread-1 synMethod loop 1 3 Thread-1 synMethod loop 2 4 Thread-1 synMethod loop 3 5 Thread-1 synMethod loop 4 6 Thread-0 synMethod loop 0 7 Thread-0 synMethod loop 1 8 Thread-0 synMethod loop 2 9 Thread-0 synMethod loop 3 10 Thread-0 synMethod loop 4 11 12 Process finished with exit code 0
第三条:当一个线程访问某对象的synchronized方法或者synchronized代码块时,其他线程对该对象的其他的synchronized方法或者synchronized代码块的访问将被阻塞。
from:https://blog.csdn.net/wanliguodu/article/details/81005560
https://blog.csdn.net/wanliguodu/article/details/81154294