多线程处理同一批数据_Java 多线程基础(一)

本文介绍了Java中多线程的基础知识,包括进程与线程的区别、线程的五种状态以及创建线程的三种方式:继承Thread类、实现Runnable接口和Callable接口。还提及了线程的优先级和常用方法,强调了线程池在实际项目中的重要性。
摘要由CSDN通过智能技术生成

简介

在接触多线程之前,在我们程序中在任意时刻都只能执行一个步骤,称之为单线程。在单线程开发的程序中所有的程序路径都是顺序执行的,前面的必须先执行,后面的才会执行。单线程的优点也很明显,相对于多线程来说更加稳定、扩展性更强、程序开发相对比较容易。但是由于每次都要等上一个任务执行完成后才能开始新的任务,导致其效率比多线程低,甚至有时候应用程序会出现假死的现象。使用多线程有利于充分发挥多处理器的功能。通过创建多线程进程,每个线程在一个处理器上运行,从而实现应用程序的并发性,使每个处理器都得到充分运行。多线程是 Java 学习的非常重要的方面,是每个 Java 程序员必须掌握的基本技能。本文是有关 Java 多线程的一些基础知识总结。

进程与线程的区别

进程

进程是操作系统资源分配的基本单位,它是操作系统的基础,是一个程序及其数据在处理机上顺序执行时所发生的活动。一个程序进入内存运行,即变成一个进程。进程是处于运行过程中的程序,并且具有一定独立功能。进程的实质就是程序在操作系统中的一次执行过程,它是动态产生的、动态销毁的,拥有自己的生命周期和各种不同的运行状态。同时,进程还具有并发性,它可以同其他进程一起并发执行,按各自独立的、不可预知的速度向前推进(PS:并发性和并行性是不同的概念,并行指的是同一时刻,两个及两个以上的指令在多个处理器上同时执行。而并发指的是同一时刻只有一条指令执行,但是多个进程可以被 CPU 快速交换执行,给我们感觉好像是多个执行在同时执行一样)。 

线程

线程是任务调度和执行的基本单位,也被称为轻量级进程,线程由线程 ID,当前指令指针(PC),寄存器集合和堆栈组成。线程不拥有系统资源,它只会拥有一点儿在运行时必不可少的资源,但是它可以与同属于同一进程的线程共享该进程所拥有的所有资源。一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程。

二者的区别

1.调度 线程作为调度和分配的基本单位,进程作为拥有资源的基本单位2.并发性 不仅进程之间可以并发执行,同一个进程的多个线程之间也可并发执行3.拥有资源 进程是拥有资源的一个独立单位,线程不拥有系统资源,但可以访问隶属于进程的资源4.系统开销 在创建或撤消进程时,由于系统都要为之分配和回收资源,导致系统的开销明显大于创建或撤消线程时的开销

创建线程的方式

在 Java 中使用 Thread 类代表线程,所有的线程对象都必须是 Thread 类或者其子类的实例,Java 中创建线程主要有以下三种方式:

方式一 继承 Thread 类

step 1 定义一个类继承自 Thread 类,然后重写该类的 run 方法,这个方法的内容表示线程要完成的任务

step 2 创建线程对象,即创建 Thread 类子类的实例

step 3 调用步骤二中创建出来的对象的 start 方法

下面是一个 Java 多线程处理一批数据的 demo: ```java import java.util.ArrayList; import java.util.List; public class MultiThreadDemo { private static final int THREAD_COUNT = 4; private static final int DATA_SIZE = 1000000; public static void main(String[] args) throws InterruptedException { // 初始化数据 List<Integer> data = new ArrayList<>(DATA_SIZE); for (int i = 0; i < DATA_SIZE; i++) { data.add(i); } // 创建线程 List<Thread> threads = new ArrayList<>(THREAD_COUNT); for (int i = 0; i < THREAD_COUNT; i++) { final int startIndex = i * DATA_SIZE / THREAD_COUNT; final int endIndex = (i + 1) * DATA_SIZE / THREAD_COUNT; Thread thread = new Thread(() -> { // 处理数据 for (int j = startIndex; j < endIndex; j++) { process(data.get(j)); } }); threads.add(thread); } // 启动线程 for (Thread thread : threads) { thread.start(); } // 等待线程执行完成 for (Thread thread : threads) { thread.join(); } // 统计结果 int result = 0; for (int i = 0; i < DATA_SIZE; i++) { result += data.get(i); } System.out.println("Result: " + result); } private static void process(int data) { // TODO: 实现数据处理的逻辑 } } ``` 在这个例子中,我们初始化了一个包含 1000000 个整数的列表,然后创建了 4 个线程处理这些数据。每个线程处理数据是均匀分配的,即第 1 个线程处理索引为 0 到 249999 的数据,第 2 个线程处理索引为 250000 到 499999 的数据,以此类推。在每个线程中,我们调用了 `process` 方法来处理数据。 在主线程中,我们启动了所有的线程,并等待它们执行完成。然后我们统计了所有数据的和,输出了结果。 需要注意的是,在多线程处理一批数据时,需要注意线程之间的同步问题。例如,如果 `process` 方法有副作用,可能会出现数据竞争的问题,导致结果不正确。可以使用 synchronized 或者 Lock 等机制来解决这个问题。 另外,多线程处理一批数据的效率并不一定比单线程处理快,因为线程之间的切换和同步也会带来一定的开销。因此,在实际应用中,需要根据具体情况来选择最合适的方案。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值