小赵本赵
发布于 2024-06-22 / 39 阅读
1
0

JAVA多线程详解【editing】

Java 给多线程编程提供了内置的支持。 一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。进程:一个进程包括由操作系统分配的内存空间,包含一个或多个线程。一个线程不能独立的存在,它必须是进程的一部分。一个进程一直运行,直到所有的非守护线程都结束运行后才能结束。

多线程的使用

  • 新建状态:

    使用 new 关键字和 Thread 类或其子类建立一个线程对象后,该线程对象就处于新建状态。它保持这个状态直到程序 start() 这个线程。

  • 就绪状态:

    当线程对象调用了start()方法之后,该线程就进入就绪状态。就绪状态的线程处于就绪队列中,要等待JVM里线程调度器的调度。

  • 运行状态:

    如果就绪状态的线程获取 CPU 资源,就可以执行 run(),此时线程便处于运行状态。处于运行状态的线程最为复杂,它可以变为阻塞状态、就绪状态和死亡状态。

  • 阻塞状态:

    如果一个线程执行了sleep(睡眠)、suspend(挂起)等方法,失去所占用资源之后,该线程就从运行状态进入阻塞状态。在睡眠时间已到或获得设备资源后可以重新进入就绪状态。可以分为三种:

    • 等待阻塞:运行状态中的线程执行 wait() 方法,使线程进入到等待阻塞状态。

    • 同步阻塞:线程在获取 synchronized 同步锁失败(因为同步锁被其他线程占用)。

    • 其他阻塞:通过调用线程的 sleep() 或 join() 发出了 I/O 请求时,线程就会进入到阻塞状态。当sleep() 状态超时,join() 等待线程终止或超时,或者 I/O 处理完毕,线程重新转入就绪状态。

  • 死亡状态:

    一个运行状态的线程完成任务或者其他终止条件发生时,该线程就切换到终止状态。

线程的优先级:Java 线程的优先级是一个整数,其取值范围是 1 (Thread.MIN_PRIORITY ) - 10 (Thread.MAX_PRIORITY )。默认情况下,每一个线程都会分配一个优先级 NORM_PRIORITY(5)。

守护线程:守护线程又称后台线程,默认创建的线程都是普通线程或称为前台线程,线程提供了一个方法setDaemon(boolean on),只有调用该方法并传入参数为true时,该线程才会被设为守护线程。守护线程与普通线程的唯一区别是:当JVM中所有的线程都是守护线程的时候,JVM就可以退出了;如果还有一个或以上的非守护线程则不会退出。(以上是针对正常退出,调用System.exit则必定会退出)。

创建一个新的线程

继承Thread

public class MyThread extends Thread {
    @Override
    public void run() {
        // 线程执行的任务
    }
}

// 创建并启动线程
MyThread thread = new MyThread();
thread.start();

实现Runnable

public class MyRunnable implements Runnable {
    @Override
    public void run() {
        // 线程执行的任务
    }
}

// 创建并启动线程
MyRunnable runnable = new MyRunnable();
Thread thread = new Thread(runnable);
thread.start();

通过 Callable 和 Future 创建线程,获取线程执行结果

public class MyCallable implements Callable<Integer> {
    @Override
    public Integer call() throws Exception {
        // 线程执行的任务,返回结果
        return 1 + 2;
    }
}

// 创建 Callable 对象和 FutureTask 对象
MyCallable callable = new MyCallable();
FutureTask<Integer> futureTask = new FutureTask<>(callable);

// 创建并启动线程
Thread thread = new Thread(futureTask);
thread.start();

// 获取 Callable 返回的结果,如果线程未执行完毕会阻塞
Integer result = futureTask.get();


/*---------------------CompletableFuture异步编程 多线程同时等待执行结果-------------------------*/
//创建线程池  
    ExecutorService executorService = Executors.newFixedThreadPool(10);  
    //开启异步任务1  
    CompletableFuture<Integer> task = CompletableFuture.supplyAsync(() -> {  
        System.out.println("异步任务1,当前线程是:" + Thread.currentThread().getId());  
        int result = 1 + 1;  
        System.out.println("异步任务1结束");  
        return result;  
    }, executorService);  

    //开启异步任务2  
    CompletableFuture<Integer> task2 = CompletableFuture.supplyAsync(() -> {  
        System.out.println("异步任务2,当前线程是:" + Thread.currentThread().getId());  
        int result = 1 + 2;  
        try {  
            Thread.sleep(3000);  
        } catch (InterruptedException e) {  
            e.printStackTrace();  
        }  
        System.out.println("异步任务2结束");  
        return result;  
    }, executorService);  

    //开启异步任务3  
    CompletableFuture<Integer> task3 = CompletableFuture.supplyAsync(() -> {  
        System.out.println("异步任务3,当前线程是:" + Thread.currentThread().getId());  
        int result = 1 + 3;  
        try {  
            Thread.sleep(4000);  
        } catch (InterruptedException e) {  
            e.printStackTrace();  
        }  
        System.out.println("异步任务3结束");  
        return result;  
    }, executorService);  

    //任务组合  
    CompletableFuture<Void> allOf = CompletableFuture.allOf(task, task2, task3);  

    //等待所有任务完成  
    allOf.get();  
    //获取任务的返回结果  
    System.out.println("task结果为:" + task.get());  
    System.out.println("task2结果为:" + task2.get());  
    System.out.println("task3结果为:" + task3.get());  

/*---------------------多线程同时等待执行结果-------------------------*/

spring中的多线程

filling...

多线程常用API与工具类

  1. Object

    1. notify() ,唤醒正在等待对象监视器的单个线程。

    2. notifyAll() ,唤醒正在等待对象监视器的所有线程。

    3. wait() ,导致当前线程等待,直到另一个线程调用该对象的 notify()方法或 notifyAll()方法。

    4. wait(long timeout) ,导致当前线程等待,直到另一个线程调用 notify()方法或该对象的 notifyAll()方法,或者指定的时间已过。

  2. Thread

    1. public Thread(String name) , 指定线程名称

    2. public void start(),线程启动

    3. public static Thread currentThread(),获取当前线程

    4. public static void sleep(long time),线程休眠

    5. setPriority(int newPriority),更改此线程的优先级

    6. public final void setDaemon(boolean on),将此线程标记为daemon线程或用户线程

  3. TimeUnit,java.util.concurrent包下面的一个类,表示给定单元粒度的时间段

CyclicBarrier和CountDownLatch

Exchanger&&Semaphore

Concurrent包

Lock接口

Condition接口

java.util.concurrent.locks包

线程池

线程安全与协作

线程间通信


评论