1. 线程通信
1.1 线程通信介绍
1.2 两条线程通信
package com.itheima.correspondence;public class CorrespondenceDemo1 {/*两条线程通信*/public static void main(String[] args) {Printer1 p = new Printer1();new Thread(new Runnable() {@Overridepublic void run() {synchronized (Printer1.class) {while (true) {try {p.print1();} catch (InterruptedException e) {e.printStackTrace();}}}}}).start();new Thread(new Runnable() {@Overridepublic void run() {synchronized (Printer1.class) {while (true) {try {p.print2();} catch (InterruptedException e) {e.printStackTrace();}}}}}).start();}}class Printer1 {int flag = 1;public void print1() throws InterruptedException {if (flag!=1){// 等待线程2Printer1.class.wait();}System.out.print("传");System.out.print("智");System.out.print("教");System.out.print("育");System.out.println();flag = 2;// 唤醒线程2Printer1.class.notify();}public void print2() throws InterruptedException {if (flag != 2) {// 等待线程1Printer1.class.wait();}System.out.print("黑");System.out.print("马");System.out.print("程");System.out.print("序");System.out.print("员");System.out.println();flag = 1;// 唤醒线程1Printer1.class.notify();}
}
1.3 三条线程通信
对于三条线程通信, 使用notifyAll(), 唤醒所有进程以避免死锁
package com.itheima.correspondence;public class CorrespondenceDemo2 {/*三条线程通信问题: sleep方法和wait方法的区别?回答:sleep方法是线程休眠, 时间到了自动醒来, sleep方法在休眠的时候, 不会释放锁.wait方法是线程等待, 需要由其它线程进行notify唤醒, wait方法在等待期间, 会释放锁.*/public static void main(String[] args) {Printer2 p = new Printer2();new Thread(new Runnable() {@Overridepublic void run() {synchronized (Printer2.class) {while (true) {try {p.print1();} catch (InterruptedException e) {e.printStackTrace();}}}}}).start();new Thread(new Runnable() {@Overridepublic void run() {synchronized (Printer2.class) {while (true) {try {p.print2();} catch (InterruptedException e) {e.printStackTrace();}}}}}).start();new Thread(new Runnable() {@Overridepublic void run() {synchronized (Printer2.class) {while (true) {try {p.print3();} catch (InterruptedException e) {e.printStackTrace();}}}}}).start();}
}class Printer2 {int flag = 1;public void print1() throws InterruptedException {if (flag != 1) {Printer2.class.wait();}System.out.print("传");System.out.print("智");System.out.print("教");System.out.print("育");System.out.println();flag = 2;Printer2.class.notifyAll();}public void print2() throws InterruptedException {if (flag != 2) {Printer2.class.wait();}System.out.print("黑");System.out.print("马");System.out.print("程");System.out.print("序");System.out.print("员");System.out.println();flag = 3;Printer2.class.notifyAll();}public void print3() throws InterruptedException {if (flag != 3) {Printer2.class.wait();}System.out.print("传");System.out.print("智");System.out.print("大");System.out.print("学");System.out.println();flag = 1;Printer2.class.notifyAll();}
}
1.4 三条线程通信的优化
package com.itheima.correspondence;import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;public class CorrespondenceDemo3 {/*三条线程通信 - 优化:将同步信号synchronized换成ReentrantLock*/public static void main(String[] args) {Printer3 p = new Printer3();new Thread(new Runnable() {@Overridepublic void run() {while (true) {try {p.print1();} catch (InterruptedException e) {e.printStackTrace();}}}}).start();new Thread(new Runnable() {@Overridepublic void run() {while (true) {try {p.print2();} catch (InterruptedException e) {e.printStackTrace();}}}}).start();new Thread(new Runnable() {@Overridepublic void run() {while (true) {try {p.print3();} catch (InterruptedException e) {e.printStackTrace();}}}}).start();}
}class Printer3 {ReentrantLock lock = new ReentrantLock();Condition c1 = lock.newCondition();Condition c2 = lock.newCondition();Condition c3 = lock.newCondition();int flag = 1;public void print1() throws InterruptedException {// 上锁lock.lock();if (flag != 1){// 线程1等待, c1绑定线程1c1.await();}System.out.print("传");System.out.print("智");System.out.print("教");System.out.print("育");System.out.println();flag = 2;c2.signal();// 解锁lock.unlock();}public void print2() throws InterruptedException {lock.lock();if (flag != 2){// 线程2等待, c2绑定线程2c2.await();}System.out.print("黑");System.out.print("马");System.out.print("程");System.out.print("序");System.out.print("员");System.out.println();flag = 3;c3.signal();lock.unlock();}public void print3() throws InterruptedException {lock.lock();if (flag != 3){// 线程3等待, c3绑定线程3c3.await();}System.out.print("传");System.out.print("智");System.out.print("大");System.out.print("学");System.out.println();flag = 1;c1.signal();lock.unlock();}
}
1.5 案例-生产消费模式
package com.itheima.producer_consumer;import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;public class WareHouse {/*** 缓冲区域*/public static boolean mark = false;public static ReentrantLock lock = new ReentrantLock();public static Condition producer = lock.newCondition();public static Condition consumer = lock.newCondition();}
package com.itheima.producer_consumer;public class Producer implements Runnable {/*生产者*/@Overridepublic void run() {while (true) {WareHouse.lock.lock();if (WareHouse.mark){try {WareHouse.producer.await();} catch (InterruptedException e) {e.printStackTrace();}}System.out.println("生产者线程生产了包子...");WareHouse.mark = true;WareHouse.consumer.signal();WareHouse.lock.unlock();}}
}
package com.itheima.producer_consumer;public class Consumer implements Runnable{/*消费者*/@Overridepublic void run() {while (true) {WareHouse.lock.lock();if (!WareHouse.mark){try {WareHouse.consumer.await();} catch (InterruptedException e) {e.printStackTrace();}}System.out.println("消费者吃了包子...");WareHouse.mark = false;WareHouse.producer.signal();WareHouse.lock.unlock();}}
}
package com.itheima.producer_consumer;public class Test {/*测试类*/public static void main(String[] args) {new Thread(new Producer()).start();new Thread(new Consumer()).start();}
}
2. 线程生命周期
注: 面试时最好能画出来
3. 线程池
~见Day15最后一节
4. 单例设计
4.1 单例设计-饿汉式
package com.itheima.single_design;public class SingleDesignDemo1 {/*单例设计模式 - 饿汉式(推荐使用, 简单不复杂)-----------------------------------------------------------------class Single1 {private Single1() {}public static final Single1 s = new Single1();}-----------------------------------------------------------------*/public static void main(String[] args) {Single1 s = Single1.getInstance();System.out.println(s);}
}class Single1 {private Single1() {}private static Single1 s = new Single1();public static Single1 getInstance() {return s;}
}
4.2 单例-懒汉式(延迟加载模式)
package com.itheima.single_design;public class SingleDesignDemo2 {/*单例设计模式 - 懒汉式 (延迟加载模式) --- 面试时可能会问到--------------------------------------------------class Single2 {private Single2() {}private static Single2 s;public static Single2 getInstance() {if (s == null) {s = new Single2();}return s;}}弊端: 在多线程并发操作的时候, 有可能创建出多个对象.--------------------------------------------------class Single2 {private Single2() {}private static Single2 s;public static Single2 getInstance() {synchronized (Single2.class) {if (s == null) {s = new Single2();}}return s;}}弊端: 效率非常低--------------------------------------------------*/public static void main(String[] args) {for (int i = 1; i <= 10; i++) {new Thread(new Runnable() {@Overridepublic void run() {Single2 s = Single2.getInstance();System.out.println(s);}}).start();}}
}class Single2 {private Single2() {}private static Single2 s;public static Single2 getInstance() {// 线程2// 线程1// 此处第一个 if (s == null) 用于提高效率, 避免线程多次重复阻塞, 影响效率if (s == null) {synchronized (Single2.class) {// 第二个 if (s == null) 避免产生不同的线程if (s == null) {s = new Single2();}}}return s;}}