java 线程详解及线程与进程的区别

Java 线程详解及线程与进程的区别

线程和进程的概念

在操作系统中,进程可以被看作是一个执行中的程序,它所占用的内存空间中包含了代码,数据,和系统资源等等。而线程则是进程中的执行单元,进程中可以拥有多个线程。

线程与进程的两个最重要的区别如下:

  • 一个进程可以有多个线程,各个线程可以并发执行
  • 一个进程内的线程共享该进程所占用的资源

Java 线程的创建和启动

Java 中的线程可以通过 Thread 类来创建和启动。以下为线程的创建和启动示例代码:

public class ThreadExample extends Thread {
    public void run() {
        System.out.println("线程运行中");
    }

    public static void main(String[] args) {
        ThreadExample thread = new ThreadExample();
        thread.start();
    }
}

上述代码中,我们先创建了一个继承自 Thread 的线程类 ThreadExample,然后在该线程类中实现了 run 方法。在 run 方法中,我们打印了一句话“线程运行中”。

在 main 方法中,我们创建了一个 ThreadExample 类型的对象 thread,然后通过调用 thread.start() 方法来启动线程。

Java 线程的状态

在 Java 中,线程一共有六种状态:

  • NEW:新创建的线程状态,线程还未启动
  • RUNNABLE:运行中的线程状态,线程正在执行或等待系统资源,例如 CPU 时间片
  • BLOCKED:阻塞中的线程状态,线程正在等待锁的时候被挂起
  • WAITING:等待中的线程状态,线程在等待另一个线程释放锁以及等待输入输出之类的操作
  • TIMED_WAITING:具有时间限制的等待中线程状态,线程在等待另一个线程释放锁或等待超时
  • TERMINATED:已结束的线程状态,线程已经执行完毕并终止

Java 线程的同步

Java 中的线程同步可以使用 synchronized 关键字来实现。以下为同步示例代码:

public class SynchronizedExample implements Runnable {
    private int num = 0;

    public synchronized void synchronizedMethod() {
        for (int i = 0; i < 5; i++) {
            System.out.println(Thread.currentThread().getName() + " synchronized num:" + num++);
        }
    }

    public void run() {
        String threadName = Thread.currentThread().getName();
        if (threadName.equals("A")) {
            synchronizedMethod();
        }
    }

    public static void main(String[] args) {
        SynchronizedExample runnable = new SynchronizedExample();
        Thread threadA = new Thread(runnable, "A");
        Thread threadB = new Thread(runnable, "B");
        threadA.start();
        threadB.start();
    }
}

上述代码中,我们创建了一个 SynchronizedExample 类型的对象 runnable,并且创建了两个线程 threadA 和 threadB,并且他们执行的是同一个 runnable 对象上的 run 方法。

在 synchronizedMethod 方法中,我们使用 synchronized 关键字来实现了线程同步,让线程 A 和线程 B 能够依次执行。

Java 线程的异常处理

在开发 Java 线程的时候,我们同样需要考虑异常处理。Java 中线程中出现的异常可以通过 UncaughtExceptionHandler 接口来捕捉处理。以下为异常处理示例代码:

public class ExceptionHandlerExample implements Runnable {
    @Override
    public void run() {
        System.out.println(1 / 0);
    }

    public static void main(String[] args) {
        ExceptionHandlerExample runnable = new ExceptionHandlerExample();
        Thread thread = new Thread(runnable);
        thread.setUncaughtExceptionHandler(new ExceptionHandler());
        thread.start();
    }
}

class ExceptionHandler implements Thread.UncaughtExceptionHandler {
    @Override
    public void uncaughtException(Thread t, Throwable e) {
        System.out.println(t.getName() + "发生了异常:" + e);
    }
}

在上述代码中,我们创建了一个 ExceptionHandlerExample 类型的对象 runnable,并且创建了一个线程 thread 来运行该对象上的 run 方法。然后我们通过调用 thread.setUncaughtExceptionHandler 方法为该线程设置了异常处理器。

在 ExceptionHandler 类中,我们实现了 UncaughtExceptionHandler 接口来定义了线程异常的处理逻辑。在 uncaughtException 方法中,我们打印了异常信息。

Java 线程池

在 Java 中,线程池可以使用 java.util.concurrent.Executors 工厂类来创建。以下为线程池示例代码:

public class ThreadPoolExample implements Runnable {
    public void run() {
        System.out.println(Thread.currentThread().getName() + "在运行");
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        ExecutorService pool = Executors.newFixedThreadPool(2);
        ThreadPoolExample instance = new ThreadPoolExample();
        pool.execute(instance);
        pool.execute(instance);
        pool.execute(instance);
        pool.execute(instance);
        pool.execute(instance);
        pool.shutdown();
    }
}

在上述代码中,我们创建了一个 ThreadPoolExample 类型的对象 instance,并且创建了一个线程池 pool 来运行该对象上的 run 方法。在 main 方法中,我们使用 ExecutorService 类型的变量 pool 调用 Executors 的 newFixedThreadPool 方法来创建一个大小为 2 的线程池。

然后我们使用 execute 方法来提交任务,每次执行都在声明一个 instance 线程对象。最后执行 pool.shutdown() 来关闭线程池。

以上为 Java 线程的基本介绍,希望对您理解 Java 线程有所帮助。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:java 线程详解及线程与进程的区别 - Python技术站

(0)
上一篇 2023年5月18日
下一篇 2023年5月18日

相关文章

  • 解决springboot的JPA在Mysql8新增记录失败的问题

    针对Spring Boot的JPA在MySQL 8新增记录失败的问题,可以采取以下步骤进行解决: 问题原因 在MySQL 8的版本中,密码加密方式由以前的mysql_native_password改成了新的加密方式caching_sha2_password,由此就导致了Spring Boot的JPA在MySQL 8新增记录失败的问题。 解决方法 修改MySQ…

    Java 2023年5月20日
    00
  • 详解Spring循环依赖的解决方案

    针对“详解Spring循环依赖的解决方案”的完整攻略,我为大家梳理了以下内容: 什么是Spring循环依赖? Spring容器中,当两个或多个bean之间形成相互依赖关系时,就会产生循环依赖。比如:A依赖B,B依赖C,C依赖A,这时就会导致循环依赖。 Spring循环依赖的解决方案 为了解决Spring容器中的循环依赖问题,Spring提供了以下三种解决方法…

    Java 2023年5月31日
    00
  • Java Apache Commons报错“PropertyVetoException”的原因与解决方法

    “PropertyVetoException”是Java的Apache Commons类库中的一个异常,通常由以下原因之一引起: 属性被否决:如果属性被否决,则可能会出现此异常。可能会尝试使用未定义的属性或尝试未正确配置属性。 以下是两个实例: 例1 如果属性被否决,则可以尝试使用正确的属性以解决此问题。例如,在Java中,可以使用以下代码: Bean be…

    Java 2023年5月5日
    00
  • java学习笔记之eclipse+tomcat 配置

    下面是Java学习笔记之Eclipse+Tomcat配置的完整攻略。 步骤一:下载和安装Eclipse和Tomcat Eclipse是一个集成开发环境(IDE),可以用于编写和调试Java代码,Tomcat是一个开源的Java Servlet容器,可以用于运行Java Web应用程序。 可以从官方网站上下载最新版本的Eclipse和Tomcat。 Eclip…

    Java 2023年6月2日
    00
  • java 虚拟机深入了解

    Java虚拟机深入了解攻略 1. 了解Java虚拟机 Java虚拟机(JVM)是Java程序运行的平台,其中的虚拟机可以理解为是一个能够执行Java字节码的虚拟计算器。 2. 学习Java虚拟机体系结构 Java虚拟机的体系结构可以分为五个部分:类加载器、运行时数据区、执行引擎、本地接口和本地方法库。 2.1 类加载器(Class Loader) 类加载器是…

    Java 2023年5月24日
    00
  • java自带命令行工具jmap、jhat与jinfo的使用实例代码详解

    Java自带命令行工具攻略 Java自带了多个命令行工具,可以对Java程序进行分析、调试和监控。其中,jmap、jhat和jinfo是非常重要的工具。本攻略将详细讲解它们的使用,包括实例代码和示例结果。 jmap jmap是Java Memory Map的缩写,是一个用于打印Java进程中内存使用情况的命令行工具。下面是jmap的常用选项: Usage: …

    Java 2023年5月19日
    00
  • JavaScript 字符串乘法

    当我们需要将一个字符串重复多次时,我们可以使用字符串乘法操作。JavaScript中字符串乘法的语法很简单,就是使用字符串和一个数字相乘,如下所示: string * number 其中,string表示要乘的字符串,number表示要重复的次数。这个操作返回一个新的字符串,是将原字符串重复指定次数后的结果。 下面我们来看两个具体的示例: 示例一 我们有一个…

    Java 2023年5月27日
    00
  • 常见的Java安全漏洞有哪些?

    常见的Java安全漏洞 Java在发展过程中,也出现了很多安全漏洞。下面是一些常见的Java安全漏洞: 1. SQL注入漏洞 SQL注入漏洞指的是攻击者利用应用程序中没有对用户输入的SQL语句参数进行验证或转义,从而在应用程序中执行恶意的SQL语句。 示例: 假设有一个查询用户姓名的SQL语句: String sql = "SELECT * FRO…

    Java 2023年5月11日
    00
合作推广
合作推广
分享本页
返回顶部