写点什么

深入理解 Java 多线程

作者:高端章鱼哥
  • 2024-03-21
    福建
  • 本文字数:1882 字

    阅读完需:约 6 分钟

深入理解 Java 多线程

Java 线程

线程使程序能够通过同时执行多个任务而更有效地运行。

线程可用于在不中断主程序的情况下在后台执行复杂的任务。

创建线程

有两种创建线程的方式。

  1. 扩展 Thread 类

可以通过扩展 Thread 类并覆盖其 run()方法来创建线程:

public class MyThread extends Thread {  public void run() {    System.out.println("This code is running in a thread");  }}
复制代码
  1. 实现 Runnable 接口

另一种创建线程的方式是实现 Runnable 接口:

public class MyRunnable implements Runnable {  public void run() {    System.out.println("This code is running in a thread");  }}
复制代码

运行线程

  1. 扩展 Thread 类

如果类扩展 Thread 类,则可以通过创建类的实例并调用其 start()方法来运行线程:

public class Main {  public static void main(String[] args) {    MyThread myThread = new MyThread();    myThread.start();    System.out.println("This code is outside of the thread");  }}
复制代码
  1. 实现 Runnable 接口

如果类实现了 Runnable 接口,则可以通过将类的实例传递给 Thread 对象的构造函数,然后调用线程的 start()方法来运行线程:

public class Main {  public static void main(String[] args) {    MyRunnable myRunnable = new MyRunnable();    Thread thread = new Thread(myRunnable);    thread.start();    System.out.println("This code is outside of the thread");  }}
复制代码

区分“扩展”和“实现”线程

主要区别在于,当一个类扩展 Thread 类时,无法扩展任何其他类,但通过实现 Runnable 接口,可以扩展另一个类,例如:

class MyClass extends OtherClass implements Runnable
复制代码

并发问题

因为线程与程序的其他部分同时运行,所以无法知道代码将按照什么顺序运行。当线程和主程序同时读取和写入相同的变量时,值是不可预测的。由此导致的问题称为并发问题。

示例

一个变量 amount 值不可预测的代码示例:

public class Main extends Thread {  public static int amount = 0;
public static void main(String[] args) { Main thread = new Main(); thread.start(); System.out.println(amount); amount++; System.out.println(amount); }
public void run() { amount++; }}
复制代码

为避免并发问题,最好尽可能少地在线程之间共享属性。如果需要共享属性,一种可能的解决方案是在使用线程可以更改的任何属性之前,使用线程的 isAlive()方法检查线程是否已完成运行。

示例

使用 isAlive()防止并发问题:

public class Main extends Thread {  public static int amount = 0;
public static void main(String[] args) { Main thread = new Main(); thread.start(); // 等待线程完成 while (thread.isAlive()) { System.out.println("Waiting..."); } // 更新amount并打印其值 System.out.println("Main program: " + amount); amount++; System.out.println("Main program: " + amount); }
public void run() { amount++; }}
复制代码

线程池

线程池是一种管理线程的资源。它允许您创建并维护一组可重用的线程。使用线程池可以提高应用程序的性能和效率。

线程安全

线程安全是指多个线程可以访问和修改数据而不导致数据损坏。使数据线程安全的一种方法是使用同步。同步是一种机制,它允许线程一次一个地访问共享数据。

常见的线程安全问题

  • 竞态条件:当多个线程同时访问共享数据并尝试对其进行更改时,就会发生竞态条件。这可能导致数据损坏。

  • 原子性:原子操作是指不可分割的操作。当多个线程尝试同时执行原子操作时,可能会导致数据损坏。

  • 可见性:当一个线程对共享数据进行更改时,其他线程必须能够看到这些更改。

避免线程安全问题

  • 使用同步

  • 使用不可变对象

  • 使用原子操作

技术前沿拓展

前端开发,你的认知不能仅局限于技术内,需要发散思维了解技术圈的前沿知识。细心的人会发现,开发内部工具的过程中,大量的页面、场景、组件等在不断重复,这种重复造轮子的工作,浪费工程师的大量时间。

介绍一款程序员都应该知道的软件JNPF快速开发平台,很多人都尝试用过它,它是功能的集大成者,任何信息化系统都可以基于它开发出来。

这是一个基于 Java Boot/.Net Core 构建的简单、跨平台快速开发框架。前后端封装了上千个常用类,方便扩展;集成了代码生成器,支持前后端业务代码生成,实现快速开发,提升工作效率;框架集成了表单、报表、图表、大屏等各种常用的 Demo 方便直接使用;后端框架支持 Vue2、Vue3。如果你有闲暇时间,可以做个知识拓展。

看完本文如果觉得有用,记得点个赞支持,收藏起来说不定哪天就用上啦~

用户头像

还未添加个人签名 2023-06-19 加入

还未添加个人简介

评论

发布
暂无评论
深入理解 Java 多线程_高端章鱼哥_InfoQ写作社区