当前位置: 首页 > article >正文

java 在方法里,开一个线程,如果报错,不影响原来的方法

java 在方法里,开一个线程,如果报错,不影响原来的方法在Java中,如果在一个方法中开启一个新的线程,并且希望即使新线程抛出异常也不影响原方法的执行,可以通过以下几种方式来实现:

1. 使用 Thread 类的异常处理机制

你可以捕获新线程中的异常,并进行处理,以确保不会影响原方法的执行。

public class ThreadExample {
    public static void main(String[] args) {
        // 调用方法
        runThread();
        System.out.println("主线程继续执行");
    }

    public static void runThread() {
        Thread thread = new Thread(() -> {
            try {
                // 模拟一个可能抛出异常的操作
                int result = 10 / 0; // 这里会抛出 ArithmeticException
            } catch (Exception e) {
                // 捕获并处理异常
                System.out.println("子线程中捕获到异常: " + e.getMessage());
            }
        });
        thread.start();
    }
}

2. 使用 ExecutorServiceFuture

使用线程池和 Future 对象,可以在捕获异常的同时确保主线程的执行。

import java.util.concurrent.*;

public class ExecutorServiceExample {
    public static void main(String[] args) {
        // 调用方法
        runThread();
        System.out.println("主线程继续执行");
    }

    public static void runThread() {
        ExecutorService executor = Executors.newSingleThreadExecutor();

        Future<?> future = executor.submit(() -> {
            try {
                // 模拟一个可能抛出异常的操作
                int result = 10 / 0; // 这里会抛出 ArithmeticException
            } catch (Exception e) {
                // 捕获并处理异常
                System.out.println("子线程中捕获到异常: " + e.getMessage());
            }
        });

        executor.shutdown();
    }
}

3. 使用 Thread.UncaughtExceptionHandler

你可以为线程设置一个未捕获异常处理器,当线程抛出未捕获的异常时,该处理器会被调用。

public class UncaughtExceptionHandlerExample {
    public static void main(String[] args) {
        // 调用方法
        runThread();
        System.out.println("主线程继续执行");
    }

    public static void runThread() {
        Thread thread = new Thread(() -> {
            // 模拟一个可能抛出异常的操作
            int result = 10 / 0; // 这里会抛出 ArithmeticException
        });

        // 为线程设置未捕获异常处理器
        thread.setUncaughtExceptionHandler((t, e) -> {
            System.out.println("子线程中捕获到异常: " + e.getMessage());
        });

        thread.start();
    }
}

总结

以上三种方法都可以确保子线程中的异常不会影响原方法的执行。选择哪种方法取决于具体的需求和场景:

  • 直接捕获异常:适用于简单的线程异常处理。
  • 使用线程池和Future:适用于需要管理多个线程的场景。
  • 使用未捕获异常处理器:适用于需要全局处理未捕获异常的场景。

通过这些方法,你可以有效地隔离子线程的异常,确保主线程的正常运行。

java 多线程 案例

在Java中,多线程编程可以通过继承Thread类或实现Runnable接口来实现。下面是两个简单的多线程案例,分别展示了如何使用这两种方式创建和启动线程。

案例一:继承 Thread

public class MyThread extends Thread {
    private String name;

    public MyThread(String name) {
        this.name = name;
    }

    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.println(name + "运行  :  " + i);
            try {
                Thread.sleep((int) (Math.random() * 1000));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        MyThread thread1 = new MyThread("线程A");
        MyThread thread2 = new MyThread("线程B");
        thread1.start();
        thread2.start();
    }
}

案例二:实现 Runnable 接口

public class MyRunnable implements Runnable {
    private String name;

    public MyRunnable(String name) {
        this.name = name;
    }

    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.println(name + "运行  :  " + i);
            try {
                Thread.sleep((int) (Math.random() * 1000));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        MyRunnable runnable1 = new MyRunnable("线程X");
        MyRunnable runnable2 = new MyRunnable("线程Y");

        Thread thread1 = new Thread(runnable1);
        Thread thread2 = new Thread(runnable2);

        thread1.start();
        thread2.start();
    }
}

案例三:通过线程池管理线程

除了直接启动线程,还可以使用线程池来管理线程的生命周期,这样可以更高效地使用资源。

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ThreadPoolExample {
    public static void main(String[] args) {
        // 创建一个固定大小的线程池,大小为3
        ExecutorService executor = Executors.newFixedThreadPool(3);

        for (int i = 0; i < 5; i++) {
            Runnable worker = new WorkerThread("线程" + i);
            executor.execute(worker);
        }

        // 关闭线程池
        executor.shutdown();

        // 等待所有线程执行完毕
        while (!executor.isTerminated()) {
        }

        System.out.println("所有线程执行完毕");
    }
}

class WorkerThread implements Runnable {
    private String name;

    public WorkerThread(String name) {
        this.name = name;
    }

    @Override
    public void run() {
        System.out.println(name + " 正在运行");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(name + " 运行结束");
    }
}

运行结果

以上三个案例分别展示了如何使用Thread类、Runnable接口以及线程池来创建和管理多线程程序。运行这些程序时,你会看到多个线程并发执行,输出结果可能会交错显示,这是多线程程序的典型特征。

总结

  • 继承Thread:适用于简单的场景,直接继承Thread类并覆盖run()方法。
  • 实现Runnable接口:更灵活,适合需要实现多继承的场景。
  • 线程池:适用于需要管理大量线程的场景,可以有效控制线程的数量和生命周期。

这些案例可以帮助你理解Java中多线程编程的基本概念和实现方式。


http://www.kler.cn/a/420824.html

相关文章:

  • 学习threejs,使用VideoTexture实现视频Video更新纹理
  • 2024年Java面试八股文大全(附答案版)
  • 贪心算法专题(四)
  • 使用 Monaco Editor 实现 ECharts 变量使用功能
  • 最新版Chrome浏览器调用ActiveX控件之allWebOffice控件
  • conda手动初始化
  • spring boot有哪些不足之处?
  • NaviveUI框架的使用 ——安装与引入(图标安装与引入)
  • 使用PyPDF2工具加载pdf文件数据
  • Linux C/C++编程之动态库
  • 使用Grafana K6来测测你的系统负载能力
  • 前端禁用 页面复制粘贴
  • SpringBoot 构建在线家具商城:系统设计与技术实现
  • element-ui的下拉框报错:Cannot read properties of null (reading ‘disabled‘)
  • Qt入门6——Qt窗口
  • python学习笔记13 python中的函数(下)
  • 40分钟学 Go 语言高并发:【实战课程】性能瓶颈分析与优化实战
  • 基于Matlab合成孔径雷达(SAR)回波信号建模与多指标质量评估
  • nodejs建立TCP服务器端和TCP客户端之间的连接
  • VisionPro、Mac、IPad、如何连接Windows 文件互传
  • YOLOv8-ultralytics-8.2.103部分代码阅读笔记-loss.py
  • 深入探索 CnosDB 可观测性最佳实践:Metrics
  • 架构师:Dubbo 服务请求失败处理的实践指南
  • 蓝桥杯真题——砍竹子(C语言)
  • 如何在Spark中使用gbdt模型分布式预测
  • 中国电信张宝玉:城市数据基础设施建设运营探索与实践