面试:单例模式、排序算法、生产者消费者、死锁
- package com.kuang.pc;
-
- /**
- * 线程之间的通信问题,生产者和消费者问题! 等待唤醒 ,通知唤醒
- * 线程交替执行 A B 操作同一个变量 num=0
- * A num+1;
- * B num-1;
- */
- public class A {
-
- public static void main(String[] args) {
- Data data = new Data();
- new Thread(()->{
- for (int i = 0; i < 10; i++) {
- try {
- data.increment();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- },"A").start();
- new Thread(()->{
- for (int i = 0; i < 10; i++) {
- try {
- data.decrement();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- },"B").start();
-
- }
-
- }
- // 判断等待,业务,通知
- class Data{//数字 资源类
- private int num = 0;
-
- //+1
- public synchronized void increment() throws InterruptedException {
- if(num!=0){
- //等待
- this.wait();
- }
- num++;
- //通知其他线程,我+1完毕了
- System.out.println(Thread.currentThread().getName()+"=>"+num);
- this.notifyAll();
- }
-
- //+1
- public synchronized void decrement() throws InterruptedException {
- if(num==0){
- //等待
- this.wait();
- }
- num--;
- //通知其他线程,我-1完毕了
- System.out.println(Thread.currentThread().getName()+"=>"+num);
- this.notifyAll();
- }
-
- }
问题A B C D 开四个线程跑,在if判断之后被唤醒,没判断条件被执行了两次增加,导致的虚假唤醒问题。
- package com.kuang.pc;
-
- /**
- * 线程之间的通信问题,生产者和消费者问题! 等待唤醒 ,通知唤醒
- * 线程交替执行 A B 操作同一个变量 num=0
- * A num+1;
- * B num-1;
- */
- public class A {
-
- public static void main(String[] args) {
- Data data = new Data();
- new Thread(()->{
- for (int i = 0; i < 10; i++) {
- try {
- data.increment();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- },"A").start();
- new Thread(()->{
- for (int i = 0; i < 10; i++) {
- try {
- data.decrement();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- },"B").start();
-
-
- new Thread(()->{
- for (int i = 0; i < 10; i++) {
- try {
- data.increment();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- },"C").start();
-
- new Thread(()->{
- for (int i = 0; i < 10; i++) {
- try {
- data.decrement();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- },"D").start();
- }
-
- }
- // 判断等待,业务,通知
- class Data{//数字 资源类
- private int num = 0;
-
- //+1
- public synchronized void increment() throws InterruptedException {
- while (num!=0){
- //等待
- this.wait();
- }
- num++;
- //通知其他线程,我+1完毕了
- System.out.println(Thread.currentThread().getName()+"=>"+num);
- this.notifyAll();
- }
-
- //+1
- public synchronized void decrement() throws InterruptedException {
- while (num==0){
- //等待
- this.wait();
- }
- num--;
- //通知其他线程,我-1完毕了
- System.out.println(Thread.currentThread().getName()+"=>"+num);
- this.notifyAll();
- }
-
- }
- package com.kuang.pc;
-
- import java.util.concurrent.locks.Condition;
- import java.util.concurrent.locks.Lock;
- import java.util.concurrent.locks.ReentrantLock;
-
- /**
- * 线程之间的通信问题,生产者和消费者问题! 等待唤醒 ,通知唤醒
- * 线程交替执行 A B 操作同一个变量 num=0
- * A num+1;
- * B num-1;
- */
- public class B {
-
- public static void main(String[] args) {
- Data1 data = new Data1();
- new Thread(()->{
- for (int i = 0; i < 10; i++) {
- try {
- data.increment();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- },"A").start();
- new Thread(()->{
- for (int i = 0; i < 10; i++) {
- try {
- data.decrement();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- },"B").start();
-
-
- new Thread(()->{
- for (int i = 0; i < 10; i++) {
- try {
- data.increment();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- },"C").start();
-
- new Thread(()->{
- for (int i = 0; i < 10; i++) {
- try {
- data.decrement();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- },"D").start();
- }
-
- }
-
-
- // 判断等待,业务,通知
- class Data1 {//数字 资源类
- private int num = 0;
-
- Lock lock=new ReentrantLock();
- Condition condition = lock.newCondition();
- // condition.await();等待
- // condition.signalAll();唤醒全部
- //+1
- public void increment() throws InterruptedException {
- lock.lock();
- try {
- //业务代码
- while (num != 0) {
- //等待
- condition.await();
- }
- num++;
- System.out.println(Thread.currentThread().getName() + "=>" + num);
- //通知其他线程,我+1完毕了
- condition.signalAll();
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- lock.unlock();
- }
-
-
- }
-
- //+1
- public void decrement() throws InterruptedException {
- lock.lock();
- try {
- //业务代码
- while (num == 0) {
- //等待
- condition.await();
- }
- num--;
- System.out.println(Thread.currentThread().getName() + "=>" + num);
- //通知其他线程,我-1完毕了
- condition.signalAll();
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- lock.unlock();
- }
-
-
- }
-
- }
任何一个新的技术,绝对不是仅仅只覆盖了原来的技术,优势,和补充!
- package com.kuang.pc;
-
- import java.util.concurrent.locks.Condition;
- import java.util.concurrent.locks.Lock;
- import java.util.concurrent.locks.ReentrantLock;
-
- /**
- * 线程之间的通信问题,生产者和消费者问题! 等待唤醒 ,通知唤醒
- * 线程交替执行 A B 操作同一个变量 num=0
- * A num+1;
- * B num-1;
- */
- public class C {
-
- public static void main(String[] args) {
- Data2 data = new Data2();
-
- new Thread(()->{
- for (int i = 0; i < 10; i++) {
- data.printA();
- }
- },"A").start();
- new Thread(()->{
- for (int i = 0; i < 10; i++) {
- data.printB();
- }
- },"B").start();
- new Thread(()->{
- for (int i = 0; i < 10; i++) {
- data.printC();
- }
- },"C").start();
-
-
- }
-
- }
- // 判断等待,业务,通知
- class Data2 {//数字 资源类
-
-
- private Lock lock=new ReentrantLock();
- private Condition condition1 = lock.newCondition();
- private Condition condition2 = lock.newCondition();
- private Condition condition3 = lock.newCondition();
-
- private int num=1;
- public void printA(){
- lock.lock();
- try {
- if (num!=1){
- //等待
- condition1.await();
- }
- num=2;
- System.out.println(Thread.currentThread().getName()+":Aaa");
- //唤醒,唤醒指定的人,B
- condition2.signal();
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- lock.unlock();
- }
-
-
- }
- public void printB(){
- lock.lock();
- try {
- if (num!=2){
- condition2.await();
- }
- num=3;
- System.out.println(Thread.currentThread().getName()+":Bbb");
- condition3.signal();
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- lock.unlock();
- }
-
- }
- public void printC(){
- lock.lock();
- try {
- if (num!=3){
- condition3.await();
- }
- System.out.println(Thread.currentThread().getName()+":Ccc");
- num=1;
- condition1.signal();
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- lock.unlock();
- }
-
- }
-
- }
-
-
精准唤醒线程 Condition