新手在学习java过程中,总会听到主线程,IO线程等,那么究竟什么是线程呢?
文章目录
目录
前言
线程是java中非常重要的学习点之一,希望本文能对读者有所帮助
一、什么是线程?
首先来看官方语言
线程是cpu调度的最小单位,一个进程中可以包含多个线程,在Android中,一个进程通常是一个App,App中会有一个主线程,主线程可以用来操作界面元素,如果有耗时操作,必须开启子线程执行,不然会出现ANR......
在我看来
线程就像是一个大厨房里的多个厨师。想象一下,你在一个繁忙的餐厅厨房里,有好几个厨师同时工作,每个厨师负责不同的任务,比如一个厨师切蔬菜,另一个厨师煮汤,还有一个厨师烤面包。他们都在同一个厨房空间里,共享一些资源,比如水槽、炉灶和食材,但每个人都在做自己独立的任务。
在计算机程序中,线程也是这样工作的。一个程序可以创建多个线程,每个线程执行程序的一部分,就像厨房里的每个厨师负责一部分工作。这些线程可以在同一时间(或几乎同一时间)运行,让程序能够同时处理多个任务,比如下载文件、播放音乐和显示视频,提高程序的效率和响应速度。
线程之间的“厨师”们需要协调,避免冲突,比如两个厨师同时使用同一个炉灶,或者两个线程同时修改同一份数据。为此,程序需要有机制来管理线程间的同步和通信,确保一切有序进行。
一句话,线程就是分工明确的工作流
二、实现线程的方式
1.继承Thread
优点是方便
缺点是每次都要新建,导致耦合不高
代码如下(示例):
Thread syncTask = new Thread(){
@Override
public void run(){
//执行耗时操作
}
}
syncTask.start();//启动线程
2.实现Runnable
优点可以交给线程池处理,耦合低
缺点是不方便传参,并且无法获取线程任务的返回结果
代码如下(示例):
public class ThreadTask implements Runnable {
@Override
public void run() {
while (true) {
System.out.println(Thread.currentThread().getName()+"线程运行中");
try {
Thread.sleep(1000);
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
}
3.实现Callable
只是在实现Runnable接口的方式创建线程的基础上,同时实现了Future接口,实现有返回值的创建线程。
代码如下(示例):
public class ThreadTask implements Callable<String> {
@Override
public String call() throws Exception {
Thread.sleep(1000); // 模拟网络延迟
// 模拟从服务获取数据的过程
String data = "Data fetched from service";
return data;
}
}
三、何为线程池
线程池简单来说可以理解位存放线程的池子,随用随取,不用单独的创建和销毁
因此,一般来说,我们需要线程实现功能时,都会使用线程池而不是实现Callnable接口
1.常用的线程池
newCachedThreadPool 可缓存线程池
newFixedThreadPool 定长线程池
newScheduledThreadPool 支持定时及周期性任务的执行
newSingleThreadExecutor 单线程,保证任务先进先出
2.线程池的7个参数
核心线程数 线程池中最小的线程数,即在线程池中一直保持的线程数量,不受空闲时间的影响
最大线程数 最大池大小
空闲线程存活时间 当线程池中的线程数超过核心线程数时,多余的线程会被回收,此参数即为非核心线程的空闲时间,超过此时间将被回收
工作队列 用于存储等待执行的任务的队列,当线程池中的线程数达到核心线程数时,新的任务将被加入工作队列等待执行。
拒绝策略 当线程池和工作队列都已经达到最大容量,无法再接收新的任务时,拒绝策略将被触发。常见的拒绝策略有抛出异常、直接丢弃任务、丢弃队列中最老的任务等。
线程工厂 用于创建新的线程,可定制线程名字、线程组、优先级等
阻塞策略 当工作队列已满时,向线程池中添加任务的策略。常见的策略有:直接抛出异常、阻塞调用者、丢弃任务等
3.代码实现
public class ThreadPoolExample {
public static void main(String[] args) {
// 创建一个固定大小的线程池
ExecutorService executor = Executors.newFixedThreadPool(5);
// 提交多个Callable任务到线程池
Future<String>[] futures = new Future[3];
for (int i = 0; i < 3; i++) {
futures[i] = executor.submit(new ThreadTaskC());
}
// 获取Callable任务的结果
for (Future<String> future : futures) {
try {
System.out.println("Result: " + future.get()); // get()会阻塞直到结果可用
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
// 关闭线程池
executor.shutdown();
while (!executor.isTerminated()) {
// 等待所有任务完成
}
}
}
总结
以上就是在下的浅薄认知,如有不足,静候留言。
烟肆暮影空落原,手握残刀梦断颧