如何理解 Java 线程的概念及线程的创建和管理,包括 Runnable 接口和 Thread 类

多线程编程是现代软件开发中的重要技术,能够显著提高程序的效率和响应速度。Java 提供了丰富的多线程编程支持,使开发者可以轻松地创建和管理线程。

1. 线程的基本概念
1.1 进程与线程
  • 进程:是操作系统中独立运行的程序,每个进程都有自己的内存空间和系统资源。
  • 线程:是进程中的一个执行单元,一个进程可以包含多个线程。线程共享进程的内存空间和资源,但每个线程有自己的执行路径。
1.2 多线程的优点
  • 提高程序响应速度:在 GUI 应用程序中,使用多线程可以保持界面的响应能力。
  • 充分利用多核处理器:多线程可以在多核处理器上并行执行,提高程序性能。
  • 简化异步编程:多线程使处理异步任务变得更加容易。
2. 创建线程

Java 提供了两种主要方式来创建线程:实现 Runnable 接口和继承 Thread 类。

2.1 实现 Runnable 接口

实现 Runnable 接口是创建线程的推荐方式,因为它避免了 Java 的单继承限制,并且更符合面向对象设计原则。

步骤:

  1. 定义一个类实现 Runnable 接口。
  2. 实现 Runnable 接口的 run 方法。
  3. 创建 Thread 对象,并将 Runnable 实现类的实例作为参数传递给 Thread 的构造函数。
  4. 调用 Thread 对象的 start 方法启动线程。

示例代码:

class MyRunnable implements Runnable {@Overridepublic void run() {for (int i = 0; i < 5; i++) {System.out.println(Thread.currentThread().getName() + " - " + i);try {Thread.sleep(1000);  // 休眠1秒} catch (InterruptedException e) {e.printStackTrace();}}}
}public class RunnableExample {public static void main(String[] args) {MyRunnable myRunnable = new MyRunnable();Thread thread1 = new Thread(myRunnable, "Thread-1");Thread thread2 = new Thread(myRunnable, "Thread-2");thread1.start();thread2.start();}
}
2.2 继承 Thread 类

继承 Thread 类是另一种创建线程的方法,但由于 Java 是单继承语言,这种方法在类需要继承其他类时不太适用。

步骤:

  1. 定义一个类继承 Thread 类。
  2. 重写 Thread 类的 run 方法。
  3. 创建 Thread 子类的实例。
  4. 调用实例的 start 方法启动线程。

示例代码:

class MyThread extends Thread {@Overridepublic void run() {for (int i = 0; i < 5; i++) {System.out.println(getName() + " - " + i);try {Thread.sleep(1000);  // 休眠1秒} catch (InterruptedException e) {e.printStackTrace();}}}
}public class ThreadExample {public static void main(String[] args) {MyThread thread1 = new MyThread();MyThread thread2 = new MyThread();thread1.setName("Thread-1");thread2.setName("Thread-2");thread1.start();thread2.start();}
}
3. 线程管理
3.1 线程生命周期

线程有以下几种状态:

  • 新建(New):线程对象被创建但未启动。
  • 就绪(Runnable):线程已启动,等待 CPU 调度。
  • 运行(Running):线程正在执行。
  • 阻塞(Blocked):线程因某种原因暂停执行,等待资源。
  • 死亡(Terminated):线程执行结束或异常终止。
3.2 线程的优先级

每个线程都有优先级,优先级较高的线程将更早被 CPU 调度执行。可以使用 setPriority 方法设置线程的优先级,范围从 1 到 10。

Thread thread = new Thread(new MyRunnable());
thread.setPriority(Thread.MAX_PRIORITY);  // 设置最高优先级
3.3 线程同步

线程同步用于解决多个线程并发访问共享资源时可能引起的数据不一致问题。Java 提供了多种同步机制。

3.3.1 同步方法

使用 synchronized 关键字修饰方法,使该方法在同一时间只能被一个线程执行。

class Counter {private int count = 0;public synchronized void increment() {count++;}public int getCount() {return count;}
}public class SynchronizedMethodExample {public static void main(String[] args) {Counter counter = new Counter();Runnable task = () -> {for (int i = 0; i < 1000; i++) {counter.increment();}};Thread thread1 = new Thread(task);Thread thread2 = new Thread(task);thread1.start();thread2.start();try {thread1.join();thread2.join();} catch (InterruptedException e) {e.printStackTrace();}System.out.println("Final count: " + counter.getCount());}
}
3.3.2 同步代码块

使用 synchronized 关键字修饰代码块,指定锁对象,以更细粒度地控制同步。

class Counter {private int count = 0;private final Object lock = new Object();public void increment() {synchronized (lock) {count++;}}public int getCount() {return count;}
}public class SynchronizedBlockExample {public static void main(String[] args) {Counter counter = new Counter();Runnable task = () -> {for (int i = 0; i < 1000; i++) {counter.increment();}};Thread thread1 = new Thread(task);Thread thread2 = new Thread(task);thread1.start();thread2.start();try {thread1.join();thread2.join();} catch (InterruptedException e) {e.printStackTrace();}System.out.println("Final count: " + counter.getCount());}
}
3.4 线程通信

线程通信用于在线程之间传递信息,Java 提供了 waitnotifynotifyAll 方法来实现线程通信。

3.4.1 wait 和 notify
  • wait:使当前线程等待,直到另一个线程调用 notifynotifyAll 方法。
  • notify:唤醒等待的线程中优先级最高的线程。
  • notifyAll:唤醒所有等待线程。

示例代码:

class SharedResource {private int value = 0;private boolean available = false;public synchronized void produce(int newValue) {while (available) {try {wait();} catch (InterruptedException e) {e.printStackTrace();}}value = newValue;available = true;System.out.println("Produced: " + value);notify();}public synchronized void consume() {while (!available) {try {wait();} catch (InterruptedException e) {e.printStackTrace();}}System.out.println("Consumed: " + value);available = false;notify();}
}public class WaitNotifyExample {public static void main(String[] args) {SharedResource resource = new SharedResource();Thread producer = new Thread(() -> {for (int i = 1; i <= 10; i++) {resource.produce(i);}});Thread consumer = new Thread(() -> {for (int i = 1; i <= 10; i++) {resource.consume();}});producer.start();consumer.start();}
}
4. 高级多线程技术
4.1 线程池

线程池是一组预先创建的线程,可以重复使用,避免频繁创建和销毁线程带来的性能开销。Java 提供了 java.util.concurrent 包中的 ExecutorService 接口和相关实现类来管理线程池。

示例代码:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class ThreadPoolExample {public static void main(String[] args) {ExecutorService executor = Executors.newFixedThreadPool(3);Runnable task = () -> {System.out.println(Thread.currentThread().getName() + " is executing task.");try {Thread.sleep(1000);  // 模拟任务执行时间} catch (InterruptedException e) {e.printStackTrace();}};for (int i = 0; i < 10; i++) {executor.submit(task);}executor.shutdown();  // 关闭线程池}
}
4.2 Callable 和 Future

Callable 接口类似于 Runnable,但可以返回结果并且可以抛出异常。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 CallableFutureExample {public static void main(String[] args) {ExecutorService executor = Executors.newFixedThreadPool(3);Callable<String> task = () -> {Thread.sleep(1000);  // 模拟任务执行时间return Thread.currentThread().getName() + " has completed task.";};Future<String> future = executor.submit(task);try {System.out.println(future.get());  // 获取任务结果} catch (InterruptedException | ExecutionException e) {e.printStackTrace();}executor.shutdown();  // 关闭线程池}
}
4.3 并发集合

Java 提供了一些线程安全的集合类,如 ConcurrentHashMapCopyOnWriteArrayListCopyOnWriteArraySet 等。

示例代码:

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;public class ConcurrentMapExample {public static void main(String[] args) {ConcurrentMap<String, Integer> concurrentMap = new ConcurrentHashMap<>();concurrentMap.put("A", 1);concurrentMap.put("B", 2);Runnable task = () -> {concurrentMap.put("C", 3);System.out.println(Thread.currentThread().getName() + " put C: " + concurrentMap.get("C"));};Thread thread1 = new Thread(task);Thread thread2 = new Thread(task);thread1.start();thread2.start();try {thread1.join();thread2.join();} catch (InterruptedException e) {e.printStackTrace();}System.out.println("Final map: " + concurrentMap);}
}
5. 线程安全问题与解决方案
5.1 线程安全问题

线程安全问题通常发生在多个线程并发访问共享资源时,导致数据不一致。常见问题包括竞态条件、死锁、饥饿和活锁。

5.2 解决方案
  • 使用同步机制:如 synchronized 关键字、显式锁(java.util.concurrent.locks.Lock)。
  • 使用线程安全类:如 java.util.concurrent 包中的线程安全集合类。
  • 避免共享资源:通过减少共享资源的使用,降低出现线程安全问题的概率。

Java 多线程编程提供了丰富的工具和类,使开发者可以灵活地创建和管理线程,从而提高程序的性能和响应能力。

通过了解线程的基本概念、创建线程的方法、线程的生命周期以及线程同步和通信机制,可以有效地解决并发编程中的各种问题。

随着 java.util.concurrent 包的引入,Java 多线程编程变得更加高效和易用,进一步提升了并发编程的开发体验。

黑马程序员免费预约咨询

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/21962.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AI大模型页面

自己做的AI&#xff0c;模仿GPT。 访问地址&#xff1a;欢迎 请大家给点意见&#xff0c;需要追加哪些功能。

前端高速成长的八个阶段

高速成长阶段一&#xff1a;学会用 Google 英文搜索。 为什么不用百度&#xff1f; 因为搜索范围与质量相差太大。用谷歌&#xff0c;你通常能在第一页找到高质量的答案&#xff0c;而在百度你可能需要花费更多时间。英文搜索并不难&#xff0c;例如遇到 React 报错&#xff0…

Windows下设置pip代理(proxy)

使用场景 正常网络情况下我们安装如果比较多的python包时&#xff0c;会选择使用这种 pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple --trusted-hostpypi.tuna.tsinghua.edu.cn 国内的镜像来加快下载速度。 但是&#xff0c;当这台被限制上…

【python】修改目标检测的xml标签(VOC)类别名

需求&#xff1a; 在集成多个数据集一同训练时&#xff0c;可能会存在不同数据集针对同一种目标有不同的类名&#xff0c;可以通过python脚本修改数据内的类名映射&#xff0c;实现统一数据集标签名的目的。 代码&#xff1a; # -*- coding: utf-8 -*- # Time : 2023/9/11 1…

出海APP遭遇大流量攻击的应对与防御策略

随着全球化的加速&#xff0c;越来越多的中国企业选择将APP推向海外市场。然而&#xff0c;这也意味着他们将面临更加复杂多变的网络安全环境&#xff0c;其中大流量DDoS攻击便是常见且破坏力巨大的威胁之一。本文将深入探讨出海APP遭遇大流量攻击的识别、应急处理及长期防御策…

如何选择实名认证接口?C++身份证二、三要素实名认证接口提供厂商

线上平台进行身份证实名认证&#xff0c;有助于保障交易的安全性&#xff0c;防止身份信息被盗用的风险&#xff0c;其主要应用于金融、在线银行、支付平台、社交媒体、账号注册、内容发布等多种应用场景。那么&#xff0c;又当如何选择实名认证接口厂家呢&#xff1f; 翔云人…

java中的注解

文章目录 定义格式使用类型内置注解元注解自定义注解 注解实现 定义 注解一般用于对程序的说明&#xff0c;想注释一样&#xff0c;但是区别是&#xff0c;注释是给人看的&#xff0c;注解是给程序看的让编译器进行编辑检查的作用&#xff0c;比如&#xff1a;Override修饰的方…

富格林:正确应对虚假暗箱计策

富格林悉知&#xff0c;当前投资者对现货黄金交易热情高涨&#xff0c;要想通过现货黄金交易获得可观的收益&#xff0c;那么对于行情的准确分析和判断便是不可或缺的。富格林认为&#xff0c;基本上每位投资者都需要花费时间和精力去学习正规的技巧提高操作技术才可正确应对虚…

osi七层网络模型安全加固

应用层加固 应用层的攻击&#xff1a; 1、针对应用层协议的攻击&#xff1a;HTTP攻击、DNS攻击、电子邮件攻击等&#xff0c;利用应用层协议的漏洞&#xff0c;构造恶意数据包&#xff0c;是目标服务器执行恶意代码或暴露敏感信息 HTTP攻击&#xff1a;XSS、CSRF、HTTP头注入…

你每天都在用的APP,原来都是Python写的!

&#x1f446;点击关注 获取更多编程干货&#x1f446; 要说Python的用途&#xff0c;那可太多了&#xff0c;也许你不知道Python是什么&#xff0c;但你一定用过它开发的产品&#xff0c;就像你可能不了解汽车引擎的构造&#xff0c;但你每天都享受着汽车带来的便利一样。 比…

stm32-DMA转运数据

在配置前要记得先定义一下DMA转运的源端数组和目标数组两个数组哦。 接下来我们就开始准备配置吧 配置 初始化 1.RCC开启时钟&#xff08;开启DMA的时钟&#xff09; void RCC_AHBPeriphClockCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState) 作用&#xff1a;开启时…

深入探讨Qt中的QVariant

深入探讨Qt中的QVariant 在Qt框架中&#xff0c;QVariant是一个非常强大的类&#xff0c;用于在运行时存储和操作不同类型的值。它类似于C标准库中的std::any或boost::any&#xff0c;能够动态存储任意类型的值&#xff0c;并且在需要时进行类型转换。本文将详细介绍QVariant的…

AbMole《丝光交织,未来可期:新型多功能丝素蛋白/透明质酸支架为脊髓修复带来新希望》

在生物医学领域&#xff0c;脊髓损伤&#xff08;Spinal Cord Injury, SCI&#xff09;的修复一直是一个巨大的挑战。由于脊髓缺乏自我修复的能力&#xff0c;一旦发生损伤&#xff0c;往往会导致永久性的功能障碍。然而&#xff0c;随着组织工程和生物材料科学的发展&#xff…

注册域名用哪个后缀好?

在互联网的世界中&#xff0c;域名是您品牌、业务或个人在线身份的基石。选择正确的域名后缀对于建立在线存在感和吸引目标受众至关重要。随着新顶级域名(New gTLDs)的涌现&#xff0c;域名后缀的选择变得多样化。本文将探讨如何选择最适合您需求的域名后缀。 传统顶级域名(TL…

如何在Weblogic环境中启动认证方式对接Zabbix监控

在WebLogic Server中&#xff0c;启动认证可用于确保只有经过授权的用户和系统能够访问WebLogic Server及其应用程序&#xff0c;通过合理配置认证提供者和安全领域&#xff0c;管理员可以有效管理和控制用户访问。 本文将详细介绍如何在Weblogic环境中配置启动认证并对接Zabb…

用域名访问的网站一定要用OV SSL证书

一、什么是域名 域名&#xff0c;英文名为Domain Name&#xff0c;是互联网上用于识别和定位计算机的层次结构式的字符标识符&#xff0c;通过一系列的字符和点来表示&#xff0c;用于在数据传输时标识计算机的电子方位。简单来说&#xff0c;域名就是网站在互联网上的地址&am…

Django视图层探索:GET/POST请求处理、参数传递与响应方式详解

系列文章目录 Django入门全攻略&#xff1a;从零搭建你的第一个Web项目Django ORM入门指南&#xff1a;从概念到实践&#xff0c;掌握模型创建、迁移与视图操作Django ORM实战&#xff1a;模型字段与元选项配置&#xff0c;以及链式过滤与QF查询详解Django ORM深度游&#xff…

【源码】源码物品销售系统多种支付接口出售源码轻松赚钱

源码物品销售系统&#xff0c;多种支付接口&#xff0c;出售源码轻松赚钱。一款基于phpmysql开发的内容付费管理系统。系统支持多种收费方式&#xff0c;免签收款&#xff0c;三级分销&#xff0c;实名认证&#xff0c; 用户投稿/奖励&#xff0c;自动升级&#xff0c;佣金提现…

oracle如何查看同义词

在Oracle数据库中&#xff0c;查看同义词的方法主要有以下几种&#xff0c;这些方法可以通过查询不同的数据字典视图来实现&#xff1a; 使用ALL_SYNONYMS视图&#xff1a; 当你想要查看数据库中所有你有权限访问的同义词时&#xff0c;可以使用ALL_SYNONYMS视图。查询语句示例…

python中的循环控制语句break与continue

学习这两个语句之前&#xff0c;我们要先了解这两个语句是什么意思&#xff1a; break&#xff1a;中断、打破的意思。所以它的跳出循环的意思 continue&#xff1a;继续的意思&#xff0c;意思是跳过当前条件&#xff0c;继续循环 新需求来了&#xff01;我们不仅要告诉 Py…