Java 多线程 学习笔记

qaq

  • 并发:在同一时刻,有多个指令在单个CPU上交替执行
  • 并行:在同一时刻,有多个指令在多个CPU上同时执行

多线程的实现方式

继承Thread类

重写run方法

//MyThread.java
public class MyThread extends Thread {
    @Override
    public void run() {
        
    }
}


//ThreadDemo.java
MyThread t = new MyThread();
t.start();

实现Runnable接口

重写run方法

//MyRun.java
public class MyRun implements Runnable {
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + "Hello");
    }
}

//ThreadDemo.java
MyRun a = new MyRun();

Thread t1 = new Thread(a);
Thread t2 = new Thread(a);

t1.start();
t2.start();

利用Callable接口和Future接口

  • 可以获取到多线程运行的结果
//MyCallable.java
public class MyCallable implements Callable<Integer> {
    @Override
    public Integer call() throws Exception {
        int sum = 0;
        for (int i = 0; i < 100; i++)
            sum += i;
        return sum;
    }
}


//ThreadDemo.java

//创建MyCallable对象,表示多线程要执行的任务
MyCallable mc = new MyCallable();
//创建FutureTask对象,管理多线程运行的结果
FutureTask<Integer> ft = new FutureTask<>(mc);

Thread t1 = new Thread(ft);
t1.start();

//获取多线程运行的结果
Integer result = ft.get();
System.out.println(result);

常见成员方法

  • String getName():返回线程名字
  • void setName(String name):设置线程名字,默认名字:Thread-X(X从0开始)
  • static Thread currentThread():获取当前线程的对象
  • static void sleep(long time):让线程休眠指定毫秒时间
  • setPriority(int newPriority):设置线程优先级(1~10),默认是5。优先级越高,越容易抢到cpu
  • final int getPriority():获取优先级
  • final void setDaemon(boolean on):设置为守护线程
  • public static void yield():出让线程/礼让线程,出让当前cpu的执行权
  • public static void join():插入线程/插队线程

调度

java中用的是抢占式调度,线程优先级越高,越容易抢到cpu

守护线程

当其他的非守护线程执行完毕后,守护线程会陆续结束

同步代码块

  • 把操作共享数据的代码锁起来
  • 锁默认打开,进去一个线程就关闭
  • 里面线程出来再打开
synchronized() {//锁对象是任意唯一对象,可以用当前类的字节码文件(MyThread.class)
    
}

同步方法

  • 把synchronized关键字加到方法上
  • 修饰符 synchronized 返回值类型 方法名(){}
  • 同步方法是锁住方法里面所有的代码
  • 锁对象不能自己指定
    • 当前方法非静态:this
    • 当前方法静态:当前类的字节码文件对象

Lock锁

  • JDK5以后有的
  • 提供了获得锁和释放锁的方法
    • void lock():获得锁
    • void unlock():释放锁
  • Lock是接口不能直接实例化
Lock lock = new ReentrantLock();

常见方法

用锁使用方法

  • void wait():当前线程等待,直到被其他线程唤醒
  • void notify():随机唤醒单个线程
  • void notifyAll():唤醒所有线程

阻塞队列

  • 实现了IterableCollectionQueueBlockingQueue这些接口
  • ArrayBlockingQueueLinkedBlockingQueue两种实现方式
  • 不需要额外写锁

方法

  • put, ``

线程池

Executors

线程池的工具类通过调用方法返回不同类型的线程池对象

  • public static ExecutorService newCachedThreadPool():创建一个上限为INT_MAX的线程池对象
  • public static ExecutorService newFixedThreadPool(int nThreads):创建有上限的线程池

成员方法

  • submit():提交任务
  • shutdown():销毁线程池

线程池多大合适

  • CPU密集型运算:
  • I/O密集型运算:
img_show