# 多线程

# 线程创建

# 继承 Thread 类

package com.imooc.thread;

class MyThread extends Thread {
  public void run() {
    System.out.println("该线程正在执行");
  }
}

public class ThreadTest {
  public static void main(String[] args) {
    MyThread myThread = new MyThread();
    myThread.start();
  }
}

# 实现 Runnable 接口

  • 只有一个 run()方法
  • Runnable 是 Java 中用以实现线程的接口
  • 任何实现线程功能的类都必须实现该接口

为什么实现 Runnable 接口?

  • Java 不支持多继承
  • 不打算重写 Thread 类的其他方法
package com.imooc.runnable;

class PrintRunnable implements Runnable {
  public void run() {
    System.out.println(Thread.currentThread().getName()+"正在运行!");
  }
}
public class Test {
  public static void main(String[] args) {
    PrintRunnable pr = new PrintRunnable();
    Thread t1 = new Thread(pr);
    t1.start();
  }
}

# Thread 常用方法

public void run() // 线程相关的代码写在该方法中
public void start() // 启动线程的方法
public static void sleep(m) // 线程休眠m毫秒的方法
public void join() // 优先执行调用join()方法的线程 抢占资源

# 线程的生命周期

  • 新建(New)
  • 可运行(Runnable)
  • 正在运行(Running)
  • 阻塞(Blocked)
  • 终止(Dead)

# sleep()方法

在指定的毫秒数内让正在执行的线程休眠

class PrintRunnable implements Runnable {

  @Override
  public void run() {
    int i = 1;
    while (i<=10) {
      System.out.println(Thread.currentThread().getName() + "正在运行" + (i++));
      try {
        Thread.sleep(1000);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
  }
}

# join()方法

  • join() 优先执行,其他线程等待调用该方法的线程结束后才能执行

  • join(long millis) 优先执行,其他线程等待该线程终止的最长时间为 millis 毫秒,然后可以执行

class PrintRunnable implements Runnable {

  @Override
  public void run() {
    for(int i=1;i<=20;i++)
      System.out.println(Thread.currentThread().getName() + "正在运行" + i + "次");
  }
}

public class Test {
  public static void main(String[] args) throws InterruptedException {
    PrintRunnable pr = new PrintRunnable();
    Thread t1 = new Thread(pr);
    t1.start();
    t1.join();
    for(int i=1;i<=20;i++)
      System.out.println("主线程运行第"+i+"次");
  }
}

# 线程的优先级

  • Java 为线程类提供了 10 个优先级
  • 优先级可以用整数 1-10 表示,超过范围会抛出异常
  • 主线程默认优先级为 5

# 优先级常量

  • MAX_PRIORITY 线程最高优先级 10
  • MIN_PRIORITY 线程最低优先级 1
  • NORM_PRIORITY 线程的默认优先级 5

# 优先级方法

  • getPriority() 获取线程优先级
  • setPriority(int newPriority) 设置线程优先级
class PrintRunnable implements Runnable {

  @Override
  public void run() {
    for(int i=1;i<=10;i++)
      System.out.println(Thread.currentThread().getName() + "正在运行" + i + "次");
  }
}

public class Test {
  public static void main(String[] args) throws InterruptedException {
    // 获取主线程的优先级
    int mainPriority = Thread.currentThread().getPriority();
    System.out.println("主线程的优先级为" + mainPriority);
    // 自定义线程
    PrintRunnable pr = new PrintRunnable();
    Thread t1 = new Thread(pr);
    // 设置优先级
    // t1.setPriority(10);
    t1.setPriority(Thread.MAX_PRIORITY);
    t1.start();
    System.out.println("线程1的优先级为" + t1.getPriority());
  }
}

# 线程同步

# 多线程运行问题

  • 各个线程通过竞争 CPU 时间而获得运行机会
  • 各线程什么时候得到 CPU 时间,占用多久,是不可预测的
  • 一个正在运行着的线程在什么地方被暂停是不确定的

# 银行存取款问题

  • 为了保证在存款或取款的时候,不允许其他线程对账户余额进行操作
  • 需要对 Bank 对象进行锁定
  • 使用关键字 synchronized 实现

# 同步

  • synchronized 关键字用在
  1. 成员方法
  2. 静态方法
  3. 语句块
// 方法不允许被打断(原子化)
public synchronized void saveAccount()
public static synchronized void saveAccount()
// 某个对象不允许其他线程访问(加锁)
synchronized(obj) {}

# 线程间通信

# 方法

  • wait()方法:中断方法的执行,使线程等待(阻塞)
  • notify()方法:唤醒处于等待的某一个线程
  • notifyAll()方法:唤醒所有处于等待的线程

# 生产消费问题

public class Queue {
  private int n;
  boolean flag = false;

  public synchronized int get() throws InterruptedException {
    if (!flag) {
      wait();
    }
    System.out.println("消费:" + n);
    flag = false; // 消费完毕
    notifyAll();
    return n;
  }

  public synchronized void set(int n) throws InterruptedException {
    if(flag) {
      wait();
    }
    System.out.println("生产:" + n);
    this.n = n;
    flag=true; // 生产完毕
    notifyAll();
  }
}
上次更新: 2/13/2025, 3:29:47 AM