synchronized
在Java实现同步可以通过给方法添加关键字synchronized修饰要同步的对象,也可以通过synchronized()方法来执行需要同步的方法,但是单独使用synchronized经常会导致不合理的现象,因此通常和wait()和notify()搭配使用。
synchronized关键字,不仅实现同步,JMM中规定,synchronized要保证可见性(不能够被缓存)
相比Lock,Synchronized使用简单,语义清晰,哪里需要点哪里。由JVM提供, 提供了多种优化方案(锁粗化、锁消除、偏向锁、轻量级锁)。锁的释放由虚拟机来完成,不用人工干预,也降低了死锁的可能性。但是不能实现公平锁、中断锁等高级功能。
synchronized与this
synchronized修饰对象自己的时候,把对象实例用作要锁的对象,等同于对象的方法被synchronized修饰,各个对象实例对方法的调用不会造成影响。
1 2 3 4 5 6 7 8 9 10 11
| class Sync{ public synchronized void S1(){ }
public void S2(){ synchronized (this){ } } }
|
synchronized与class
synchronized修饰对象的class对象时,把对象的class作为全局锁的对象,等同于对象的静态方法synchronized修饰,各个对象实例对方法的调用会相互影响。
1 2 3 4 5 6 7 8 9 10 11
| class Sync2{ public static synchronized void S1(){ }
public void S2(){ synchronized (Sync2.class){ } } }
|
synchronized与成员变量
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 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| class Callme { void Call(String msg) { System.out.print("[" + msg); try { Thread.sleep(1000); } catch(InterruptedException e) { System.out.println("Interrupted"); } System.out.println("]"); } }
class Caller implements Runnable { String msg; Callme target; Thread t; public Caller(Callme targ, String s) { this.msg = s; this.target = targ; t = new Thread(this); t.start(); } public void run() { this.target.Call(msg); } }
public class LearnThreadSyn { public static void main(String args[]) { Callme target = new Callme(); Caller obj1 = new Caller(target, "Hello"); Caller obj2 = new Caller(target, "Synchronized"); Caller obj3 = new Caller(target, "World"); try { obj1.t.join(); obj2.t.join(); obj3.t.join(); } catch (InterruptedException e) { System.out.println("Interrupted"); }
} }
|
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 53 54 55 56 57 58 59 60 61 62
| package helloworld;
class Callme { synchronized void Call(String msg) { System.out.print("[" + msg); try { Thread.sleep(1000); } catch(InterruptedException e) { System.out.println("Interrupted"); } System.out.println("]"); } }
class Caller implements Runnable { String msg; Callme target; Thread t; public Caller(Callme targ, String s) { this.msg = s; this.target = targ; t = new Thread(this); t.start(); } public void run() { this.target.Call(msg); } }
public class LearnThreadSyn { public static void main(String args[]) { Callme target = new Callme(); Caller obj1 = new Caller(target, "Hello"); Caller obj2 = new Caller(target, "Synchronized"); Caller obj3 = new Caller(target, "World"); try { obj1.t.join(); obj2.t.join(); obj3.t.join(); } catch (InterruptedException e) { System.out.println("Interrupted"); } } }
|
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 53 54 55 56 57 58 59 60 61 62 63 64
| package helloworld;
class Callme { void Call(String msg) { System.out.print("[" + msg); try { Thread.sleep(1000); } catch(InterruptedException e) { System.out.println("Interrupted"); } System.out.println("]"); } }
class Caller implements Runnable { String msg; Callme target; Thread t; public Caller(Callme targ, String s) { this.msg = s; this.target = targ; t = new Thread(this); t.start(); } public void run() { synchronized(this.target) { this.target.Call(msg); } } }
public class LearnThreadSyn { public static void main(String args[]) { Callme target = new Callme(); Caller obj1 = new Caller(target, "Hello"); Caller obj2 = new Caller(target, "Synchronized"); Caller obj3 = new Caller(target, "World"); try { obj1.t.join(); obj2.t.join(); obj3.t.join(); } catch (InterruptedException e) { System.out.println("Interrupted"); } } }
|
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 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
| class Q { int n; synchronized int get() { System.out.println("Got :" + n); return n; } synchronized void put(int n) { this.n = n; System.out.println("Put :" + n); } }
class Producer implements Runnable { Q q; Producer(Q q) { this.q =q; new Thread(this, "Producer").start(); } public void run() { int i = 0; while(true) { q.put(i++); } } }
class Consumer implements Runnable { Q q; Consumer(Q q) { this.q = q; new Thread(this, "Consumer").start(); } public void run() { while(true) { q.get(); } } }
public class LearnThreadComm { public static void main(String args[]) { Q q = new Q(); new Producer(q); new Consumer(q); System.out.println("Stop"); } }
|