前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java 多线程 (Part1: Java线程基础)

Java 多线程 (Part1: Java线程基础)

作者头像
JiahuiZhu1998
修改2023-06-16 00:09:03
3070
修改2023-06-16 00:09:03
举报
文章被收录于专栏:JiahuiZhu1998_技术笔记

Java Thread 实现/创建方式

  • 使用 Class Thread
  • 使用 Interface Runnable (No Return Value 无返回值)
代码语言:javascript
复制
//  最简单的 Thread 和 Runnable 的配套使用
Runnable task = () -> {
    String threadName = Thread.currentThread().getName();
    System.out.println("Hello " + threadName);
}; // 用 Lambda 表达式实现 Runnable接口

task.run();

Thread thread = new Thread(task);
thread.start();

System.out.println("Done!");
代码语言:javascript
复制
//  带 thread sleep 的 Thread 和 Runnable 的配套使用
Runnable runnable = () -> {
    try {
        String name = Thread.currentThread().getName();
        System.out.println("Foo " + name);
        TimeUnit.SECONDS.sleep(1);
        System.out.println("Bar " + name);
    }
    catch (InterruptedException e) {
        e.printStackTrace();
    }
};

Thread thread = new Thread(runnable);
thread.start();

  • 使用 ExecutorService (线程池接口)
代码语言:javascript
复制
// 最简单的 ExecutorService 使用的例子
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.submit(() -> {
    String threadName = Thread.currentThread().getName();
    System.out.println("Hello " + threadName);
});

// 以下是ScheduledExecutorService 的使用, 也是ExecutorService的一种
ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
// => Hello pool-1-thread-1

代码语言:javascript
复制
// ExecutorService 使用 shutdown 和 shutdownNow 这两个方法去 Interrupt Running线程
try {
    System.out.println("attempt to shutdown executor");
    executor.shutdown();
    executor.awaitTermination(5, TimeUnit.SECONDS);
}
catch (InterruptedException e) {
    System.err.println("tasks interrupted");
}
finally {
    if (!executor.isTerminated()) {
        System.err.println("cancel non-finished tasks");
    }
    executor.shutdownNow();
    System.out.println("shutdown finished");
}
  • 使用 Callable<Class> (和 Runnable 一样也是一个Interface) ((Has Return Value 有返回值) 有返回值的Runnable
代码语言:javascript
复制
// 使用 Callable的最简单例子, 使用 sleep 可以让thread运行的更加久
Callable<Integer> task = () -> {
    try {
        TimeUnit.SECONDS.sleep(1);
        return 123;
    }
    catch (InterruptedException e) {
        throw new IllegalStateException("task interrupted", e);
    }
};
  • 使用 Future (和 Runnable 一样也是一个Interface)。预约排号的接口
  • 使用线程池 ( 下方代码有 newFixedThreadPool 线程池)
代码语言:javascript
复制
// 使用 Future 的最简单例子
Runnable task = () -> {
    String threadName = Thread.currentThread().getName();
    System.out.println("Hello " + threadName);
};
ExecutorService executor = Executors.newFixedThreadPool(1);
Future<Integer> future = executor.submit(task);

System.out.println("future done? " + future.isDone());

Integer result = future.get();

System.out.println("future done? " + future.isDone());
System.out.print("result: " + result);

Java ThreadPool 线程池有哪些

一共有4种线程池

  1. newCachedThreadPool 可缓存线程池, 线程闲置60s便会被回收
  2. newFixedThreadPool 定长线程池, 线程闲置不会被回收
  3. newScheduledThreadPool 定时任务线程池, 核心线程闲置立刻被回收
  4. newSingleThreadExecutor 只有唯一线程的线程池, 支持 FIFO, LIFO; 如果唯一线程dead, 会new 一个新线程

Java Thread LifeCycle 线程的生命周期

  1. New 新建
  2. Runnable 就绪
  3. Blocked 阻塞
  4. Waiting 等待
  5. Timed Waiting 使用 timeout时间点的等待
  6. Terminated 终止
代码语言:javascript
复制
// Java program to demonstrate thread states
// Java 生命周期的 例子
class thread implements Runnable {
    public void run()
    {
        // moving thread2 to timed waiting state
        try {
            Thread.sleep(1500);
        }
        catch (InterruptedException e) {
            e.printStackTrace();
        }
 
        System.out.println(
            "State of thread1 while it called join() method on thread2 -"
            + Test.thread1.getState());
        try {
            Thread.sleep(200);
        }
        catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
 
public class Test implements Runnable {
    public static Thread thread1;
    public static Test obj;
 
    public static void main(String[] args)
    {
        obj = new Test();
        thread1 = new Thread(obj);
 
        // thread1 created and is currently in the NEW
        // state.
        System.out.println(
            "State of thread1 after creating it - "
            + thread1.getState());
        thread1.start();
 
        // thread1 moved to Runnable state
        System.out.println(
            "State of thread1 after calling .start() method on it - "
            + thread1.getState());
    }
 
    public void run()
    {
        thread myThread = new thread();
        Thread thread2 = new Thread(myThread);
 
        // thread1 created and is currently in the NEW
        // state.
        System.out.println(
            "State of thread2 after creating it - "
            + thread2.getState());
        thread2.start();
 
        // thread2 moved to Runnable state
        System.out.println(
            "State of thread2 after calling .start() method on it - "
            + thread2.getState());
 
        // moving thread1 to timed waiting state
        try {
            // moving thread1 to timed waiting state
            Thread.sleep(200);
        }
        catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(
            "State of thread2 after calling .sleep() method on it - "
            + thread2.getState());
 
        try {
            // waiting for thread2 to die
            thread2.join();
        }
        catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(
            "State of thread2 when it has finished it's execution - "
            + thread2.getState());
    }
}

Java Thread 线程终止的方式

  1. 正常运行结束
  2. 用 exit flag boolean值 , 用 exit flag 当作 while loop 判断条件,判断条件为false时,线程终止
  3. 用 Interrupt 结束 当 Thread 处于 Blocked,使用 interrupt(), 并 catch InterrupttedException,最后 break 跳出循环结束thread 当 Thread不处于 Blocked, 使用 interrupt() 中 isInterrupted() 判断loop 是否结束, 和上方exit flag boolean原理一样
  4. 用 stop 结束 (线程不安全) thread.stop() 会释放所有Lock并破坏数据, 不建议使用

Java Thread 中 start, run, sleep, wait 分别是什么

代码语言:javascript
复制
Thread thread = new Thread(new Runnable);
thread.start(); // thread 被开启, 进入 Runnable 就绪状态
thread.run(); // thread 被分配到CPU时间片后, 就会执行 thread.run() 运行线程
thread.sleep(1); // thread 的 static method, 让thread睡眠, 不释放Lock, 其他thread不能访问
thread.wait(); // thread 的 Object method, 让thread进入等待池, 释放Lock, 其他thread可以访问
// wait() 被使用后, 用 notify() 或者 notifyAll() 进行唤醒 

Java 后台线程是什么

又叫 守护线程, 用 setDaemon(true) 设置; gc thread(垃圾回收线程) 就是一种守护线程; 守护线程在 JVM里面进行工作

Java 线程的基本方法

372_Untitled.png
372_Untitled.png
  1. Wait 线程等待 使用wait 进入 Waiting 状态
  2. Sleep 线程睡眠 使用sleep 进入 Timed Wating状态
  3. Yield 线程让步 使用yield 让出 CPU执行时间片
  4. Interrupt 线程中断 使用interrupt 将 thread 从 RUNNING 变成 Terminated
  5. Join 等待其他线程Terminated 使用Join,将 thread 从Running 变成Blocked,等待其他thread Terminated
  6. Notify 线程唤醒 使用 notify 将 thread 从 Waiting /Timed Waiting 变成 Running (只唤醒一个线程)
  7. 其他线程中的函数 7.1 sleep() 强迫thread sleep 7.2 isAlive() 判断thread 是否存活 7.3 join() 等待线程终止 7.4 activeCount() 活跃的thread 数量 7.5 enumerate() 枚举所有thread 7.6 currentThread() 当前thread 7.7 isDaemon() 是否是守护thread 7.8 setDaemon() 设置为守护thread 7.9 setName() 设置 name of thread 7.10 wait() 强迫 thread wait

JAVA 线程的上下文切换 (Context Switch)

CPU上执行多任务,任务状态保存,再加载,这个过程称为上下文切换

线程上下文切换
线程上下文切换
  • Process 进程
  • Context 上下文: 某一时间点 CPU register和pc的内容
  • register
  • pc --- 专用的 register
  • PCB (Process Control Block ). --- 在上下文切换中保存信息在PCB
  • 上下文切换 --- 挂起一个process,存储状态(上下文),找到下一个存储状态(上下文),恢复对应process,切换成功

JAVA 线程上下文切换原因

  1. 当前任务时间片用完,cpu调度下一个任务
  2. 当前任务被阻塞,cpu调度下一个任务
  3. 多个任务抢占Lock,没有抢到Lock,被挂起,继续下一任务
  4. 代码挂起任务,让出cpu时间
  5. Hardware Interrupt

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系转载前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Java Thread 实现/创建方式
  • Java ThreadPool 线程池有哪些
  • Java Thread LifeCycle 线程的生命周期
  • Java Thread 线程终止的方式
  • Java Thread 中 start, run, sleep, wait 分别是什么
  • Java 后台线程是什么
  • Java 线程的基本方法
  • JAVA 线程的上下文切换 (Context Switch)
  • JAVA 线程上下文切换原因
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档