首页 > 其他分享 >八股必会内容

八股必会内容

时间:2022-11-03 19:12:22浏览次数:80  
标签:八股 Thread lock InterruptedException try num 内容 必会 new

八股必会内容

生产者消费者

Synchronized 版本

重点是一定要用while来判断,否则会出现虚假唤醒(那什么虚假唤醒呢,虚假唤醒就是由于把所有线程都唤醒了,但是只有其中一部分是有用的唤醒操作,其余的唤醒都是无用功,对于不应该被唤醒的线程而言,便是虚假唤醒。)

对于这个例子中,假设A完成了+1的任务,那么会notifyAll(),而C也是+1的线程,应当继续去wait,如果是if的话直接继续执行+1就出问题了。因此应当用while,当不该被唤醒是自己继续去睡。

package com.ldl.test;
//-Xms10m -Xms10m -XX:+PrintGCDetails

public class Main{
    public static void main(String[] args) throws Exception {
//        Main main = new Main();
        Data data = new Data();
        new Thread(()->{ try { for (int i = 0; i < 10; i++) data.increasement(); } catch (InterruptedException e) { e.printStackTrace(); } },"A").start();
        new Thread(()->{ try { for (int i = 0; i < 10; i++) data.decreasement(); } catch (InterruptedException e) { e.printStackTrace(); } },"B").start();
        new Thread(()->{ try { for (int i = 0; i < 10; i++) data.increasement(); } catch (InterruptedException e) { e.printStackTrace(); } },"C").start();
        new Thread(()->{ try { for (int i = 0; i < 10; i++) data.decreasement(); } catch (InterruptedException e) { e.printStackTrace(); } },"D").start();
    }

}

class Data{
    private int  num =0;
    public  synchronized void increasement() throws InterruptedException {
        while (num!=0){ //num为0的时候才去操作
            this.wait();
        }
        num++;
        System.out.println(Thread.currentThread().getName()+"=>"+num);
        this.notifyAll();
    }
    public  synchronized void decreasement() throws InterruptedException {
        while(num==0){//num不为0的时候才去操作
            this.wait();
        }
        num--;
        System.out.println(Thread.currentThread().getName()+"=>"+num);
        this.notifyAll();
    }
}

Lock版本

流程: 判断等待业务通知

不指定下一个线程

package com.ldl.test;
//-Xms10m -Xms10m -XX:+PrintGCDetails

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Main {
    public static void main(String[] args) throws Exception {
//        Main main = new Main();
        Data data = new Data();
        new Thread(() -> { try { for (int i = 0; i < 10; i++) data.increasement(); } catch (InterruptedException e) { e.printStackTrace(); } }, "A").start();
        new Thread(() -> { try { for (int i = 0; i < 10; i++) data.decreasement(); } catch (InterruptedException e) { e.printStackTrace(); } }, "B").start();
        new Thread(() -> { try { for (int i = 0; i < 10; i++) data.increasement(); } catch (InterruptedException e) { e.printStackTrace(); } }, "C").start();
        new Thread(() -> { try { for (int i = 0; i < 10; i++) data.decreasement(); } catch (InterruptedException e) { e.printStackTrace(); } }, "D").start();
    }

}

class Data {
    private int num = 0;
    private Lock lock = new ReentrantLock();
    private Condition condition = lock.newCondition();
    public  void increasement() throws InterruptedException {
        lock.lock();
        try {
            while (num != 0) { //num为0的时候才去操作
                condition.await();
            }
            num++;
            System.out.println(Thread.currentThread().getName() + "=>" + num);
            condition.signalAll();
        } finally {
            lock.unlock();
        }
    }

    public synchronized void decreasement() throws InterruptedException {
        lock.lock();
        try {
            while (num == 0) {//num不为0的时候才去操作
                condition.await();
            }
            num--;
            System.out.println(Thread.currentThread().getName() + "=>" + num);
            condition.signalAll();
        } finally {
            lock.unlock();
        }
    }
}

指定下一个线程

  1. 需要一个标志位去记录应该到哪个执行了
  2. 需要Condition唤醒对应的线程
package com.ldl.test;
//-Xms10m -Xms10m -XX:+PrintGCDetails

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Main {
    public static void main(String[] args) throws Exception {
//        Main main = new Main();
        Data data = new Data();
        new Thread(() -> { try { for (int i = 0; i < 10; i++) data.printA(); } catch (InterruptedException e) { e.printStackTrace(); } }, "A").start();
        new Thread(() -> { try { for (int i = 0; i < 10; i++) data.printB(); } catch (InterruptedException e) { e.printStackTrace(); } }, "B").start();
        new Thread(() -> { try { for (int i = 0; i < 10; i++) data.printC(); } catch (InterruptedException e) { e.printStackTrace(); } }, "C").start();
    }

}

class Data {
    private int num = 1; //1A 2B 3C
    private Lock lock = new ReentrantLock();
    private Condition condition1 = lock.newCondition();
    private Condition condition2 = lock.newCondition();
    private Condition condition3 = lock.newCondition();

    public void printA() throws InterruptedException {
        lock.lock();
        try {
            while (num!=1){
                condition1.await();
            }
            System.out.println(Thread.currentThread().getName()+"AAAAA");
            num=2;
            condition2.signal();
        } finally {
            lock.unlock();
        }
    }
    public void printB() throws InterruptedException {
        lock.lock();
        try {
            while (num!=2){
                condition2.await();
            }
            System.out.println(Thread.currentThread().getName()+"BBBBB");
            num=3;
            condition3.signal();
        } finally {
            lock.unlock();
        }
    }
    public void printC() throws InterruptedException {
        lock.lock();
        try {
            while (num!=3){
                condition3.await();
            }
            System.out.println(Thread.currentThread().getName()+"CCCCC");
            num=1;
            condition1.signal();
        } finally {
            lock.unlock();
        }
    }

}

标签:八股,Thread,lock,InterruptedException,try,num,内容,必会,new
From: https://www.cnblogs.com/Liang2021/p/16855536.html

相关文章