线程,进程,并行,并发(区别,联系,应用)
并行与并发
理解:
并发是单核处理,并行是多核处理
并发是轮流执行,并行使同时执行
并行可用于:大数据、分布式、多线程等等
并不是任何任务都适合并发处理(例如某些任务必须要根据其他任务的数据才能执行的程序)
并行大多通过分治法实现,分治法也要有下限
并行:多个线程可以同时执行,每一个时间段,可以有多个线程同时执行。
并发:多个线程同时竞争一个位置,竞争到的才可以执行,每一个时间段只有一个线程在执行。
进程和线程:
(看图,真的比较全面了QAQ)
进程
是指一个内存中运行中的应用程序。每个进程都有自己独立的一块内存空间,一个应用程序可以同时启动多个进程。 进程是系统进行资源分配的最小单位。
有独立的内存空间,进程中的数据存放空间(堆空间和栈空间)是独立的,至少有一个线程。
线程
是指进程中的一个执行任务(控制单元),一个进程可以同时并发运行多个线程,及任务的分块处理
一个进程至少有一个线程,为了提高效率,可以在一个进程中开启多个执行任务,即多线程。
堆空间是共享的,栈空间是独立的,线程消耗的资源也比进程小,相互之间可以影响的,又称为轻型进程或进程元。
创建和启动线程:(转载自链接: link.https://blog.csdn.net/qq_44705164/article/details/112058091)
启动线程一共有三种方法:继承类,实现接口,匿名内部类。
一、启动线程的第一种方法:继承Thread类
二、启动线程的第二种方式:实现Runnable接口
三、启动线程的第三种方式:实现Callable接口
这个很详细,清楚
多线程
多线程出现的原因:
为了解决负载均衡问题,充分利用CPU资源.为了提高CPU的使用率,采用多线程的方式去同时完成几件事情而不互相干扰。
多线程的好处:
1.使用线程可以把占据时间长的程序中的任务放到后台去处理
2.程序运行效率提高
3.在一些等待的任务实现上如用户输入,文件读取和网络收发数据等,线程就比较有用了.
多线程的缺点:
1.如果有大量的线程,会影响性能,因为操作系统需要在它们之间切换.
2.更多的线程需要更多的内存空间
3.线程中止需要考虑对程序运行的影响.
4.通常块模型数据是在多个线程间共享的,需要防止线程死锁情况的发生
多线程与并行
因为涉及的知识太多,在此就不一一说明,请参考大佬的文章,写得很详细很赞。
linkhttps://blog.csdn.net/ftell/article/details/79353571
如果有多个任务,最好用线程池,否则就要为逐个任务创建线程,这种做法会导致低吞吐量和低性能。
线程池
优势
(1)降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。
(2)提高响应速度。当任务到达时,任务可以不需要等到线程创建就能立即执行。
(3)提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。
功能线程池
Executors封装好了 4 种常见的功能线程池,如下:
定长线程池(FixedThreadPool)
特点:只有核心线程,线程数量固定,执行完立即回收,任务队列为链表结构的有界队列。
应用场景:控制线程最大并发数。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Demo {
public static void main(String[] args) {
//1.创建可固定长度的线程池
ExecutorService newExecutorService = Executors.newFixedThreadPool(3);
//创建了10个线程
for (int i = 0; i < 10; i++) {
int temp = i;
newExecutorService.execute(new Runnable() {
@Override
public void run() {
System.out.println("threadName;"+Thread.currentThread().getName()+",i"+temp);
}
});
}
}
}
定时线程池(ScheduledThreadPool )
特点:核心线程数量固定,非核心线程数量无限,执行完闲置 10ms 后回收,任务队列为延时阻塞队列。
应用场景:执行定时或周期性的任务。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import static java.util.concurrent.TimeUnit.*;
public class Demo {
public static void main(String[] args) {
//1.创建可定时线程池
ScheduledExecutorService newScheduledThreadPool = Executors.newScheduledThreadPool(5);
for (int i = 0; i < 10; i++) {
final int temp = i;
newScheduledThreadPool.schedule(new Runnable() {
public void run() {
System.out.println("i:" + temp);
}
}, 3, TimeUnit.SECONDS);
}
}
}
可缓存线程池(CachedThreadPool)
特点:无核心线程,非核心线程数量无限,执行完闲置 60s 后回收,任务队列为不存储元素的阻塞队列。如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
应用场景:执行大量、耗时少的任务。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Demo1 {
public static void main(String[] args) {
//1.创建可缓存的线程池,可重复利用
ExecutorService newExecutorService = Executors.newCachedThreadPool();
//创建了10个线程
for (int i = 0; i < 10; i++) {
int temp = i;
newExecutorService.execute(new Runnable() {
@Override
public void run() {
System.out.println("threadName;"+Thread.currentThread().getName()+",i"+temp);
}
});
}
}
}
单线程化线程池(SingleThreadExecutor)
特点:创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。只有 1 个核心线程,无非核心线程,执行完立即回收,任务队列为链表结构的有界队列。
应用场景:不适合并发但可能引起 IO 阻塞性及影响 UI 线程响应的操作,如数据库操作、文件操作等。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import static java.util.concurrent.TimeUnit.*;
public class Demo {
public static void main(String[] args) {
//1.创建单线程
ExecutorService newSingleThreadExecutor = Executors.newSingleThreadExecutor();
for (int i = 0; i < 10; i++) {
final int index = i;
newSingleThreadExecutor.execute(new Runnable() {
@Override
public void run() {
System.out.println("index:" + index);
try {
Thread.sleep(200);
} catch (Exception e) {
// TODO: handle exception
}
}
});
}
newSingleThreadExecutor.shutdown();
}
}