多线程基础

1. 线程创建的几种方式

2. 锁的类型

  • 在学习JUC之前,加锁、等待、唤醒 分别使用的是 (synchronized、lock(ReentrantLock))、wait、notify,这几个方法是属于Object的
  • 在学习JUC开始,学会使用lock的newCondition方法来建立监视器,使用condition.await、condition.signal取代wait和notify
  • 使用condition为每个线程创建一个监视器,配合await和signal可以达到唤醒指定线程的效果
//交替打印AB各50次
public class Test01 {
    public static void main(String[] args) {
        PrintClass printClass = new PrintClass();
        new Thread(() -> {
            for (int i = 0; i < 50; i++) {
                printClass.printAStr();
            }

        }, "A").start();

        new Thread(() -> {
            for (int i = 0; i < 50; i++) {
                printClass.printBStr();
            }
        }, "B").start();
    }
}

class PrintClass {
    private Integer printNumber = 100;
    Lock lock = new ReentrantLock();
    Condition condition1 = lock.newCondition();
    Condition condition2 = lock.newCondition();
    
    void printAStr() {
        lock.lock();
        try {
            String name = Thread.currentThread().getName();
            while (name.equals("A") && printNumber % 2 != 0) {
                condition1.await();
            }
            printNumber--;
            System.out.println(Thread.currentThread().getName() + "==>A");
            condition2.signal();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    void printBStr() {
        lock.lock();
        try {
            String name = Thread.currentThread().getName();
            while (name.equals("B") && printNumber % 2 == 0) {
                condition2.await();
            }
            printNumber--;
            System.out.println(Thread.currentThread().getName() + "==>B");
            condition1.signal();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
}

3. 线程池

多线程基础_第1张图片

  • ExecutorService 的 submit 和 execute都可以执行 实现了 Runnable 接口的 任务,但是submit 执行的 任务 是可以拿到返回值的,execute则没有
  • 如果 执行 的多个任务中有一个发生了异常,execute 抛出异常,其他线程继续执行新任务,submit 则没有提示(只有主动 Future.get 才能拿到异常信息),其他线程继续执行
  • 如果需要 捕获 线程执行任务时的异常信息,可以在任务代码中加上try catch,但是比较麻烦,推荐重写 afterExecute 方法,参数为 Runnable 和 Throwable,可以通过判断 Throwable 是否有值来 捕获打印异常信息(抖音上刷到的)
    多线程基础_第2张图片

4. 项目中常用的线程池创建

你可能感兴趣的:(JavaEE基础,java,开发语言)