SynchronizedTest类,用来表示取票功能
package concurency.chapter6; public class SynchronizedTest implements Runnable { public static final int MAX = 250; private int index = 0; @Override public void run() { while(true) { if(ticket()) break; } } // synchronized 此时锁的是 this 锁的是一个对象,别弄错了 private synchronized boolean ticket() { if(index >= MAX) return true; try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " " + (++index)); return false; } }Ticket 模拟游乐园放票
package concurency.chapter6; public class Ticket { public static void main(String[] args) { final SynchronizedTest synRunnable = new SynchronizedTest(); Thread t1 = new Thread(synRunnable, "窗口1"); Thread t2 = new Thread(synRunnable, "窗口2"); Thread t3 = new Thread(synRunnable, "窗口3"); t1.start(); t2.start(); t3.start(); } } synchronized 同步方法时,其实是同步的this对象下面可以证明
package concurency.chapter6; public class SynchronizedThis { public static void main(String[] args) { LockThis l1 = new LockThis(); new Thread("thread1"){ @Override public void run() { l1.m1(); } }.start(); new Thread("thread2"){ @Override public void run() { l1.m2(); } }.start(); } } class LockThis { public synchronized void m1() { try { System.out.println(Thread.currentThread().getName() + " method1"); Thread.sleep(3_000); } catch (InterruptedException e) { e.printStackTrace(); } } public synchronized void m2() { try { System.out.println(Thread.currentThread().getName() + " method2"); Thread.sleep(3_000); } catch (InterruptedException e) { e.printStackTrace(); } } } synchronized 同步静态方法时,其实是同步的class package concurency.chapter6; public class SynchronizedThis { public static void main(String[] args) { new Thread("thread1"){ @Override public void run() { LockThis.m1(); } }.start(); new Thread("thread2"){ @Override public void run() { LockThis.m2(); } }.start(); } } class LockThis { public static synchronized void m1() { try { System.out.println(Thread.currentThread().getName() + " method1"); Thread.sleep(3_000); } catch (InterruptedException e) { e.printStackTrace(); } } public static synchronized void m2() { try { System.out.println(Thread.currentThread().getName() + " method2"); Thread.sleep(3_000); } catch (InterruptedException e) { e.printStackTrace(); } } } 死锁小案例Service1 两个方法. m1和m2
package concurency.chapter7; public class Service1 { private final Object lock1 = new Object(); public Service2 service2; public Service1(Service2 service2) { this.service2 = service2; } public void m1() { synchronized(lock1) { System.out.println("---m1---"); service2.s1(); } } public void m2() { synchronized(lock1) { System.out.println("---m2---"); } } }Service2 两个方法, s1和s2
package concurency.chapter7; public class Service2 { public void s1() { synchronized (lock2) { System.out.println("---s1---"); } } public void s2() { synchronized (lock2) { System.out.println("---s2---"); service1.m2(); } } private final Object lock2 = new Object(); public Service1 service1; void setService1(Service1 service1) { this.service1 = service1; } }死锁尝试
package concurency.chapter7; public class DeadLockTest { public static void main(String[] args) { Service2 service2 = new Service2(); Service1 service1 = new Service1(service2); service2.setService1(service1); new Thread() { @Override public void run() { while(true) service2.s2(); } }.start(); new Thread() { @Override public void run() { while(true) service1.m1(); } }.start(); } }jstack命令查看线程
Found one Java-level deadlock: ============================= "Thread-1": waiting to lock monitor 0x0000000017ceddd8 (object 0x00000000d5f7e150, a java.lang.Object), which is held by "Thread-0" "Thread-0": waiting to lock monitor 0x0000000017cec938 (object 0x00000000d5f806c8, a java.lang.Object), which is held by "Thread-1" Java stack information for the threads listed above: =================================================== "Thread-1": at concurency.chapter7.Service2.s1(Service2.java:6) - waiting to lock <0x00000000d5f7e150> (a java.lang.Object) at concurency.chapter7.Service1.m1(Service1.java:16) - locked <0x00000000d5f806c8> (a java.lang.Object) at concurency.chapter7.DeadLockTest$2.run(DeadLockTest.java:21) "Thread-0": at concurency.chapter7.Service1.m2(Service1.java:21) - waiting to lock <0x00000000d5f806c8> (a java.lang.Object) at concurency.chapter7.Service2.s2(Service2.java:13) - locked <0x00000000d5f7e150> (a java.lang.Object) at concurency.chapter7.DeadLockTest$1.run(DeadLockTest.java:13) Found 1 deadlock. 生产者与消费者 单个生产者 单个消费者 package concurency.chapter8; public class ConsumerAndProducer { int index = 0; private final Object LOCK = new Object(); volatile boolean isProduce = false; private void produce() { synchronized(LOCK) { if( isProduce ) { try { LOCK.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } else { // 没生产过 index++; System.out.println("product->" + index); isProduce = true; LOCK.notify(); } } } private void consume() { synchronized (LOCK) { if(isProduce) { System.out.println("consume->" + index); isProduce = false; LOCK.notify(); } else { try { LOCK.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } public static void main(String[] args) { ConsumerAndProducer cp = new ConsumerAndProducer(); new Thread("producer") { @Override public void run() { while(true) cp.produce(); } }.start(); new Thread("consumer") { @Override public void run() { while (true) cp.consume(); } }.start(); } } 多个生产者 多个消费者 package concurency.chapter8; import java.util.stream.Stream; public class ConsumerAndProducerV2 { int index = 0; private final Object LOCK = new Object(); volatile boolean isProduce = false; private void produce() { synchronized (LOCK) { while(isProduce) { try { LOCK.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } index++; System.out.println(Thread.currentThread().getName() + " " + index); isProduce = true; LOCK.notifyAll(); } } private void consume() { synchronized (LOCK) { while(!isProduce) { try { LOCK.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(Thread.currentThread().getName() + " " + index); isProduce = false; LOCK.notifyAll(); } } public static void main(String[] args) { ConsumerAndProducerV2 cp = new ConsumerAndProducerV2(); Stream.of("Producer1", "Producer2", "Producer3").forEach((name)->{ new Thread(name) { @Override public void run() { while (true) { cp.produce(); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); }); Stream.of("Consumer1", "Consumer2", "Consumer3", "Consumer4").forEach((name)->{ new Thread(name) { @Override public void run() { while(true) { cp.consume(); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); }); } } wait和sleep区别sleep是Thread的方法,而wait是object的方法
sleep will not release the monitor(LOCK), but wait will release the monitor(LOCK) and add to the object monitor waiting queue.
use sleep not depend on the monitor, but wait need(synchronized).