t01_多线程

进程与线程

进程:进程是程序的基本执行实体

线程:线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位

在Java中,进程(Process)和线程(Thread)是两个并发执行的概念,用于实现多任务处理和并发执行。它们都是操作系统和编程语言级别的概念,用于管理和执行程序的不同部分。

  1. 进程(Process): 进程是计算机中运行的程序的执行实例。每个进程都有自己的独立内存空间和系统资源,包括文件句柄、网络连接等。进程之间相互隔离,一个进程的崩溃通常不会影响其他进程。进程之间的通信通常需要使用特定的机制,如进程间通信(Inter-Process Communication,IPC)。在Java中,可以使用进程来执行不同的Java应用程序。
  2. 线程(Thread): 线程是在同一个进程内部运行的执行单元。一个进程可以包含多个线程,它们共享同一进程的内存空间和系统资源。由于线程共享内存,线程之间的通信和数据共享相对容易。但也正因为共享资源,需要特别注意线程安全问题,避免出现竞态条件等并发问题。在Java中,线程是通过Thread类或实现Runnable接口来创建的。

并发与并行

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

并行:在同一时刻,有多个指令在多个CPU上同时执行。

多线程实现的三个方式

1、继承Thread类

public class CreateThread extends Thread{
    public static void main(String[] args) {
        CreateThread createThread = new CreateThread();
        CreateThread createThread2 = new CreateThread();
        createThread.start();//开启线程
        createThread2.start();//开启线程
        // System.out.println(createThread.getName());
    }
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println(getName()+"--"+i);//注意在当前线程中可以直接使用当前线程的方法
        }
    }
}

从运行结果可以发现两个线程是交替执行的,运行结构如下图:

image-20230808171123956

2、实现Runnable接口

public class CreateRunnable implements Runnable{
    public static void main(String[] args) {
        CreateRunnable runnable=new CreateRunnable();//创建CreateRunnable对象,表示多线程要执行的任务
        Thread thread1 = new Thread(runnable);
        Thread thread2 = new Thread(runnable);
        Thread thread3 = new Thread(runnable);
        thread1.start();
        thread2.start();
        thread3.start();
    }
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            Thread thread = Thread.currentThread();//获取当前线程的对象
            System.out.println(thread.getName()+"--"+i);//注意在当前线程中可以直接使用当前线程的方法
        }
    }
}

image-20230808172446456

3、利用Callable接口和Future接口的方式实现

public class CreateCallable implements Callable<Integer> {
    public static void main(String[] args) throws Exception {
        CreateCallable callable1= new CreateCallable();//创建对象,创建执行的任务
        CreateCallable callable2= new CreateCallable();
        FutureTask<Integer> futureTask = new FutureTask<>(callable1);//创建FutureTask对象,管理多线成功运行的结构
        Thread thread = new Thread(futureTask);//创建线程的对象,传入任务
        thread.start();//启动线程
        Integer o = futureTask.get();//获取线程的返回结果
        System.out.println(o);
    }
    @Override
    public Integer call() throws Exception {
        for (int i = 0; i < 10; i++) {
            Thread thread = Thread.currentThread();
            System.out.println(thread.getName()+"--"+i);
        }
        return 1;
    }
}

线程的方法

@Test
public void test2(){
    Thread thread = Thread.currentThread();//获取当前线程对象
    System.out.println(thread);
    thread.setName("threadname");//设置线程名称
    System.out.println(thread.getName());//获取当前线程名称
    System.out.println(thread.getName());
}

守护线程

package com.xccvt.demo11_thread.method;

public class TestThread1 extends Thread {
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println(getName()+" -- "+i);
        }
    }
}

package com.xccvt.demo11_thread.method;

public class TestThread2 extends Thread {
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println(getName()+" -- "+i);
        }
    }
}

package com.xccvt.demo11_thread.method;

public class TestMethod {
    public static void main(String[] args) {
        TestThread1 testThread1 = new TestThread1();
        TestThread2 testThread2 = new TestThread2();
        //当其他的非守护线程执行完毕之后,守护线程会陆续结束,可以看到TestThread1执行完毕后,TestThread2陆续结束执行,TestThread2本来可以执行到99的
        testThread2.setDaemon(true);//将线程testThread1设置为守护线程,
        testThread1.setName("TestThread1");
        testThread2.setName("TestThread2");
        testThread1.start();
        testThread2.start();
    }
}

image-20230808181017726

礼让线程

public class TestThread1 extends Thread {
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println(getName()+" -- "+i);
            Thread.yield();//设置礼让线程,设置后会停止此线程执行,重新选择分配线程
        }
    }
}

插入线程

@Test
public void test4() throws InterruptedException {
    TestThread1 testThread2 = new TestThread1();
    // testThread2.
    testThread2.start();
    testThread2.join();//把testThread2这个线程插入到当前线程之前执行
    for (int i = 0; i < 10; i++) {
        System.out.println(Thread.currentThread().getName()+" -- "+i);
        Thread.yield();//设置礼让线程,设置后会停止此线程执行,重新选择分配线程
    }
}

线程的声明周期

image-20230808183603584

常用方法

静态方法 描述
currentThread() 获取当前正在执行的线程对象。
sleep(long millis) 使当前线程休眠指定的毫秒数。
yield() 建议线程调度器将CPU时间让给其他线程。
interrupt() 中断线程,设置线程的中断状态为true。
interrupted() 测试当前线程是否被中断,并清除中断状态。
isInterrupted() 测试线程是否被中断,不清除中断状态。
join() 等待指定线程执行完毕,然后继续当前线程。
sleep(long millis, int nanos) 使线程休眠指定的毫秒数和纳秒数。
activeCount() 返回当前线程组中活动线程的估计数。
enumerate(Thread[] tarray) 将当前线程组及其子组中的所有活动线程复制到数组。
setDefaultUncaughtExceptionHandler() 设置默认未捕获异常处理程序。
getDefaultUncaughtExceptionHandler() 获取默认未捕获异常处理程序。
方法 描述
Thread类的构造方法:
Thread() 创建一个新线程。
Thread(String name) 创建一个新线程,并指定线程名称。
Thread(Runnable target) 创建一个新线程,并指定Runnable对象。
Thread(Runnable target, String name) 创建一个新线程,指定Runnable对象和名称。
Thread类的常用方法:
start() 启动线程,调用run()方法。
run() 线程的执行逻辑,需要重写。
getName() 获取线程名称。
setName(String name) 设置线程名称。
getId() 获取线程ID。
isAlive() 判断线程是否存活。
join() 等待线程执行结束。
sleep(long millis) 让线程休眠指定时间。
yield() 放弃当前线程的CPU时间,让其他线程执行。
设置线程优先级:
getPriority() 获取线程优先级。
setPriority(int priority) 设置线程优先级。
Thread类的静态常量:
MIN_PRIORITY 最低优先级。
NORM_PRIORITY 正常优先级。
MAX_PRIORITY 最高优先级。
守护线程:
setDaemon(boolean on) 将线程设置为守护线程。
isDaemon() 判断线程是否为守护线程。

蹩脚翻译

术语 英文含义 在Java中的含义
Thread 线程 表示一个执行单元,用于并发执行代码。
Runnable 可运行的,可操作的 一个接口,表示可执行的任务,通过线程执行。
Callable 可调用的 一个接口,类似于Runnable,但可以返回结果或抛出异常。
Future 未来,将来的 一个接口,表示异步计算的结果,可用于获取任务的结果。
posted @   六个小豹  阅读(9)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek “源神”启动!「GitHub 热点速览」
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· DeepSeek R1 简明指南:架构、训练、本地部署及硬件要求
· 2 本地部署DeepSeek模型构建本地知识库+联网搜索详细步骤
点击右上角即可分享
微信分享提示