synchronized
练习一:
1 2 3 4 5 6 7 8 9 10 11 12 13 public class _001_Synchronized_O { private int count = 10 ; private Object o = new Object (); public void m () { synchronized (o) { count--; System.out.println(Thread.currentThread().getName() + " count = " + count); } } }
练习二:
1 2 3 4 5 6 7 8 9 10 11 12 public class _002_Synchronized_This { private int count = 10 ; public void m () { synchronized (this ) { count--; System.out.println(Thread.currentThread().getName() + " count = " + count); } } }
练习三:
1 2 3 4 5 6 7 8 9 10 public class _003_Synchronized_M { private int count = 10 ; public synchronized void m () { count--; System.out.println(Thread.currentThread().getName() + " count = " + count); } }
练习四:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 public class _004_Synchronized_StaticM { private static int count = 10 ; public synchronized static void m () { count--; System.out.println(Thread.currentThread().getName() + " count = " + count); } public static void mm () { synchronized (_004_Synchronized_StaticM.class){ count--; System.out.println(Thread.currentThread().getName() + " count = " + count); } } }
Runnable
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 public class _005_T_R implements Runnable { private int count = 10 ; @Override public synchronized void run () { count--; System.out.println(Thread.currentThread().getName() + " count = " + count); } public static void main (String[] args) { _005_T_R tR = new _005_T_R (); for (int i = 0 ; i < 5 ; i++) { new Thread (tR, "Thread" + i).start(); } } }
同步和非同步方法同时调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 public class _006_T_SynAndM { public synchronized void m1 () { System.out.println(Thread.currentThread().getName() + " m1 start..." ); try { Thread.sleep(1000 ); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " m1 end..." ); } public void m2 () { try { Thread.sleep(500 ); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " m2" ); } public static void main (String[] args) { _006_T_SynAndM t = new _006_T_SynAndM (); new Thread (() -> t.m1(), "t1" ).start(); new Thread (() -> t.m2(), "t2" ).start(); } }
业务的读写方法都需加锁
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 public class _007_T_Account { String name; double balance; public synchronized void set (String name, double balance) { this .name = name; try { Thread.sleep(1000 ); } catch (InterruptedException e) { e.printStackTrace(); } this .balance = balance; } public synchronized double getBalance (String name) { return this .balance; } public static void main (String[] args) { _007_T_Account account = new _007_T_Account (); new Thread (() -> account.set("zhangsan" , 100.0 )).start(); try { TimeUnit.SECONDS.sleep(1 ); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(account.getBalance("zhangsan" )); try { TimeUnit.SECONDS.sleep(2 ); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(account.getBalance("zhangsan" )); } }
可重入锁
练习一:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public class _008_T_Syn2 { synchronized void m1 () { System.out.println("m1 start" ); try { TimeUnit.SECONDS.sleep(1 ); } catch (InterruptedException e) { e.printStackTrace(); } m2(); } synchronized void m2 () { try { TimeUnit.SECONDS.sleep(2 ); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("m2" ); } }
练习二:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 public class _009_T_T_Syn2 { synchronized void m () { System.out.println("m start" ); try { TimeUnit.SECONDS.sleep(1 ); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("m end" ); } public static void main (String[] args) { new TT ().m(); } } class TT extends _009_T_T_Syn2 { @Override synchronized void m () { System.out.println("child m start" ); super .m(); System.out.println("child m end" ); } }
多线程出现异常,默认情况锁会释放
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 public class _010_T_Exception { int count = 0 ; synchronized void m () { System.out.println(Thread.currentThread().getName() + " start" ); while (true ) { count++; System.out.println(Thread.currentThread().getName() + " count" + count); try { TimeUnit.SECONDS.sleep(1 ); } catch (InterruptedException e) { e.printStackTrace(); } if (count == 5 ) { int i = 1 / 0 ; } } } public static void main (String[] args) { _010_T_Exception tTryCatch = new _010_T_Exception (); Runnable r = new Runnable () { @Override public void run () { tTryCatch.m(); } }; new Thread (r, "t1" ).start(); try { TimeUnit.SECONDS.sleep(3 ); } catch (InterruptedException e) { e.printStackTrace(); } new Thread (r, "t2" ).start(); } }
volatile
练习一:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 public class _011_T_Volatile { volatile boolean running = true ; void m () { System.out.println("m start" ); while (running) { } System.out.println("m end!" ); } public static void main (String[] args) { _011_T_Volatile tVolatile = new _011_T_Volatile (); new Thread (tVolatile::m, "t1" ).start(); try { TimeUnit.SECONDS.sleep(1 ); } catch (InterruptedException e) { e.printStackTrace(); } tVolatile.running = false ; } }
练习二:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 public class _012_T_VolatileAndSyn { volatile int count = 0 ; void m () { for (int i = 0 ; i < 10000 ; i++) count++; } public static void main (String[] args) { _012_T_VolatileAndSyn tVolatileAndSyn = new _012_T_VolatileAndSyn (); List <Thread> threads = new ArrayList <>(); for (int i = 0 ; i < 10 ; i++) { threads.add(new Thread (tVolatileAndSyn::m, "thread-" + i)); } threads.forEach((o) -> o.start()); threads.forEach((o) -> { try { o.join(); } catch (InterruptedException e) { e.printStackTrace(); } }); System.out.println(tVolatileAndSyn.count); } }
练习三:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 public class _013_T_VolatileAndSyn2 { int count = 0 ; synchronized void m () { for (int i = 0 ; i < 10000 ; i++) count++; } public static void main (String[] args) { _013_T_VolatileAndSyn2 tVolatileAndSyn2 = new _013_T_VolatileAndSyn2 (); List <Thread> threads = new ArrayList <>(); for (int i = 0 ; i < 10 ; i++) { threads.add(new Thread (tVolatileAndSyn2::m, "thread-" + i)); } threads.forEach((o) -> o.start()); threads.forEach((o) -> { try { o.join(); } catch (InterruptedException e) { e.printStackTrace(); } }); System.out.println(tVolatileAndSyn2.count); } }
AtomicXXX 类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 public class _014_T_Atomic { AtomicInteger count = new AtomicInteger (0 ); void m () { for (int i = 0 ; i < 10000 ; i++) { count.incrementAndGet(); System.out.println(Thread.currentThread().getName() + " count:" + count); } } public static void main (String[] args) { _014_T_Atomic tAtomic = new _014_T_Atomic (); List <Thread> threads = new ArrayList <>(); for (int i = 0 ; i < 10 ; i++) { threads.add(new Thread (tAtomic::m, "thread-" + i)); } threads.forEach((thread -> thread.start())); threads.forEach((thread -> { try { thread.join(); } catch (InterruptedException e) { e.printStackTrace(); } })); System.out.println(tAtomic.count); } }
synchronized 优化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 public class _015_T_SynOptimize { int count = 0 ; synchronized void m1 () { try { TimeUnit.SECONDS.sleep(2 ); } catch (InterruptedException e) { e.printStackTrace(); } count++; try { TimeUnit.SECONDS.sleep(2 ); } catch (InterruptedException e) { e.printStackTrace(); } } void m2 () { try { TimeUnit.SECONDS.sleep(2 ); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (this ){ count++; } try { TimeUnit.SECONDS.sleep(2 ); } catch (InterruptedException e) { e.printStackTrace(); } } }
避免将锁定对象的引用变成另外的对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 public class _016_T_Object { Object o = new Object (); void m () { synchronized (o) { while (true ) { try { TimeUnit.SECONDS.sleep(1 ); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()); } } } public static void main (String[] args) { _016_T_Object tObject = new _016_T_Object (); new Thread (tObject::m, "t1" ).start(); try { TimeUnit.SECONDS.sleep(3 ); } catch (InterruptedException e) { e.printStackTrace(); } Thread t2 = new Thread (tObject::m, "t2" ); tObject.o = new Object (); t2.start(); } }
不要以字符串的常量作为锁定对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 public class _017_T_String { String s1 = "Hello" ; String s2 = "Hello" ; void m1 () { synchronized (s1) { } } void m2 () { synchronized (s2) { } } }
源码:https://github.com/V-Vincen/threads/tree/master/src/main/java/com/example/_exercise
If you like this blog or find it useful for you, you are welcome to comment on it. You are also welcome to share this blog, so that more people can participate in it. If the images used in the blog infringe your copyright, please contact the author to delete them. Thank you !