Java中多线程特点的总结


进程的概念

  • 进程是指可执行程序并存放在计算机存储器的一个指令序列,它是一个动态执行的过程;
  • 线程是比进程还要小的运行单位,一个进程包含多个线程;
  • 线程可以看作一个子程序;
  • 线程调度的先后次序是随机的。

线程的创建(两种方法)

  • 创建一个Thread类,或者一个Thread子类的对象;
  • 创建一个实现Runnable接口的类的对象。
new MyThread().start()  //方法一,通过创建Thread子类的对象创建进程
new Thread(new MyRunnable()).start()  //方法二,通过Runnable接口类传入Thread类构造函数,构造Thread对象,此方法更为常用,更适合需要继承另一个父类的情况

Thread类中的常用方法

方法 功能
public void run() 线程相关的代码写在该方法中,一般需要重写
public void start() 启动线程的方法
public static void sleep(long m) 线程休眠m毫秒的方法
public void join() 优先执行调用join()方法的线程,抢占资源

创建一个实现Runnable接口的类的对象

  • 只有一个方法run();

  • Runnable是Java中用以实现线程的接口;

  • 任何实现线程功能的类都必须实现该接口;

  • 使用Runnable接口创建线程的原因

    1. Java不支持多继承,如果继承Thread类的同时还需要继承别的类就没法实现了,因此通过接口的形式实现继承;
    2. 不打算重写Thread类的其他方法。
  • Runnable接口实现类的创建和使用示例代码如下:

public static void main(String[] args){
        PrintRunnable td = new PrintRunnable();
        Thread td1=new Thread(td);
        td1.start();
}
public class PrintRunnable implements Runnable{
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()
                +"线程正在执行!");
    }
}
  • 使用Runnable接口实现类的时候需要先实例化接口实现类的对象,再去实例化一个Thread类的对象来运行实现类定义的线程。

线程的状态

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

线程的生命周期

线程的生命周期示意图

sleep方法应用

  • Thread类的方法;
public static void sleep(long millis)
  • 作用:在指定的毫秒数内让正在执行的线程休眠(暂停执行);
  • 参数为休眠的时间,单位是毫秒。

join方法应用

  • Thread类的方法;
public final void join()
  • 作用:等待调用该方法的线程结束后才能执行;
public final void join(long millis)
  • 作用:等待该线程终止的最长时间为millis毫秒;
  • 抢占CPU使用权,迫使其他线程放弃CPU使用权。

线程优先级

  • Java为线程类提供了10个优先级;

  • 优先级可以用整数1-10表示,超过范围会抛出异常;

  • 主线程默认优先级5;

  • 数字越大,表示优先级越高;

  • 优先级常量:

    • MAX_PRIORITY:线程的最高优先级10;
    • MIN_PRIORITY:线程的最低优先级1;
    • NORM_PRIORITY:线程的默认优先级5(与主线程相同)。
  • 优先级相关的方法:

方法 说明
public int getPriority() 获取线程优先级的方法
public void setPriority(int newPriority) 设置线程优先级的方法

多线程运行问题

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

线程同步问题

  • 以取款为例,说明为什么要引入线程同步这个概念

    1. 为了保证在存款或取款的时候,不允许其他线程对账户余额进行操作;
    2. 需要将Bank对象进行锁定;
    3. 使用关键字synchronized实现,可以确保共享对象在同一个时刻只能被一个线程访问,进一步保证执行完整性。
  • synchronized关键字用在

    • 成员方法
    • 静态方法
    • 语句块
public synchronized void saveAccount(){}  //成员方法
public static synchronized void saveAccount(){} //静态方法
synchronized (obj){...}   //语句块,obj指的是需要被锁定的对象,{...}是指作用语句块,即作用范围

进程间通信

  • wait()方法:中断方法的执行,使线程等待;
  • notify()方法:唤醒处于等待的某个线程,使其结束等待;
  • notifyAll()方法:唤醒所有处于等待的线程,使它们结束等待;
  • 以生产者消费者的例子可以很好地说明通信需求的原因。

文章作者: 南航古惑仔
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 南航古惑仔 !
  目录