Java中的基本并发工具

72 阅读4分钟

2.1 引言

Java并发编程的基本工具 Java 提供了一系列用于并发编程的基础工具,使开发者能够创建和管理多线程程序。这些工具包括 Thread 类、Runnable 接口、Callable 接口和 Future 接口等。通过这些工具,开发者可以实现线程的创建、管理和结果获取,为构建高性能并发应用程序打下基础。

本文的内容结构 本文将介绍 Java 并发编程的基本工具,主要内容包括:

Thread 类 Runnable 接口 Callable 和 Future

2.2 Thread类

创建和启动线程的方法 在 Java 中,Thread 类是创建和管理线程的基本工具。可以通过以下两种方式创建线程:

继承 Thread 类 实现 Runnable 接口,并将其作为参数传递给 Thread 对象 继承 Thread 类 通过继承 Thread 类,可以直接创建一个新的线程类,并重写 run() 方法:

public class MyThread extends Thread { @Override public void run() { System.out.println("Thread is running..."); }

public static void main(String[] args) {
    MyThread thread = new MyThread();
    thread.start(); // 启动线程
}

} 实现 Runnable 接口 实现 Runnable 接口并将其实例传递给 Thread 对象:

public class MyRunnable implements Runnable { @Override public void run() { System.out.println("Runnable is running..."); }

public static void main(String[] args) {
    Thread thread = new Thread(new MyRunnable());
    thread.start(); // 启动线程
}

} 常用方法和属性的介绍 Thread 类提供了一些常用的方法和属性,用于管理线程的生命周期和控制线程行为:

start():启动线程,调用线程的 run() 方法 run():线程执行的任务代码,需要重写 sleep(long millis):使当前线程休眠指定的毫秒数 join():等待线程执行完成 interrupt():中断线程 isInterrupted():检查线程是否被中断 getId():获取线程的唯一标识符 getName():获取线程的名称 setName(String name):设置线程的名称 getPriority():获取线程的优先级 setPriority(int priority):设置线程的优先级 示例:

public class ThreadMethodsDemo { public static void main(String[] args) { Thread thread = new Thread(() -> { System.out.println("Thread is running..."); try { Thread.sleep(2000); // 休眠2秒 } catch (InterruptedException e) { System.out.println("Thread was interrupted"); } System.out.println("Thread completed."); });

    thread.start();
    try {
        thread.join(); // 等待线程执行完成
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

    System.out.println("Main thread completed.");
}

}

2.3 Runnable接口

使用Runnable实现线程 Runnable 接口是一个函数式接口,只有一个抽象方法 run()。通过实现 Runnable 接口,可以将任务定义为一个可运行的对象,并将其作为参数传递给 Thread 对象,从而实现线程的创建和管理。

示例:

public class RunnableDemo implements Runnable { @Override public void run() { System.out.println("Runnable is running..."); }

public static void main(String[] args) {
    Thread thread = new Thread(new RunnableDemo());
    thread.start(); // 启动线程
}

} Runnable的优势和应用场景 优势:

实现多继承:Java 不支持多继承,但允许实现多个接口。通过实现 Runnable 接口,可以避免因为继承 Thread 类而无法继承其他类的问题。 任务与线程分离:将任务与线程分离,使得任务可以复用,并且可以更灵活地控制任务的执行。 应用场景:

在需要定义明确的任务逻辑并通过线程执行时,可以使用 Runnable 接口。 当需要实现多继承时,使用 Runnable 接口比继承 Thread 类更灵活。

2.4 Callable和Future

Callable接口的概念 Callable 接口类似于 Runnable 接口,但与 Runnable 不同的是,Callable 可以返回结果并抛出异常。Callable 接口是一个泛型接口,定义如下:

public interface Callable { V call() throws Exception; } 通过实现 Callable 接口,可以定义一个返回结果的任务,并在任务执行完成后获取结果。

使用Future获取线程执行结果的示例 Future 接口用于表示异步计算的结果。通过 Future 接口,可以检查计算是否完成、等待计算完成并获取结果。

示例:

import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future;

public class CallableFutureDemo { public static void main(String[] args) { ExecutorService executor = Executors.newSingleThreadExecutor();

    // 定义一个Callable任务
    Callable<Integer> task = () -> {
        System.out.println("Callable task is running...");
        Thread.sleep(2000); // 模拟耗时计算
        return 42; // 返回结果
    };

    // 提交任务并获取Future对象
    Future<Integer> future = executor.submit(task);

    // 执行其他操作
    System.out.println("Main thread is running...");

    try {
        // 获取Callable任务的执行结果
        Integer result = future.get();
        System.out.println("Result from callable task: " + result);
    } catch (InterruptedException | ExecutionException e) {
        e.printStackTrace();
    } finally {
        executor.shutdown();
    }

    System.out.println("Main thread completed.");
}

}

在这个示例中,我们创建了一个 Callable 任务,并使用 ExecutorService 提交任务,返回一个 Future 对象。通过 Future 对象,我们可以异步地获取任务的执行结果,并进行后续处理。

结论

本文介绍了 Java 并发编程的基本工具,包括 Thread 类、Runnable 接口、Callable 和 Future 接口。通过这些工具,开发者可以实现线程的创建、管理和结果获取,为构建高性能并发应用程序打下基础。