Java 多线程 线程池

(问)多线程下单例模式下全局变量共享问题

(面)多线程调用单例类中的方法会不会造成线程安全问题?
答案:不会。
局部变量不会受多线程影响;但成员变量会受到多线程影响。
多个线程应该是调用的同一个对象的同一个方法;
如果方法里无成员变量,那么不受任何影响;
如果方法里有成员变量,只有读操作,不受影响;存在写操作,考虑多线程影响值
.
当多个线程同时访问同一个方法的时候,jvm会给每个线程分配单独的局域变量,这样就不会出现问题了。

一 Java多线程

Java中的多线程 https://www.cnblogs.com/wxd0108/p/5479442.html

线程的生命周期

线程通常都有五种状态,创建、就绪、运行、阻塞和死亡
在这里插入图片描述

Thread 和 Runnable的区别

实例化线程对象有所不同:
extends Thread :t.start();
implements Runnable :new Thread(t).start();

实现Runnable接口比继承Thread类所具有的优势:
1):适合多个相同的程序代码的线程去处理同一个资源
2):可以避免java中的单继承的限制(不能访问父类的私有成员?)
3):增加程序的健壮性,代码可以被多个线程共享,代码和数据独立
4):线程池只能放入实现Runable或callable类线程,不能直接放入继承Thread的类

run()和start()方法的区别

run方法:是线程的任务处理逻辑的入口方法,它由Java虚拟机在运行相应线程时直接调用,而不是由应用代码进行调用。
调用run方法其实就是当作普通的方法的方式调用。并没有创建一个线程,程序中依旧只有一个主线程,必须等到run()方法里面的代码执行完毕,才会继续执行下面的代码,这样就没有达到加入线程的目的。

start方法:是启动相应的线程。启动一个线程实际是请求Java虚拟机运行相应的线程,而这个线程何时能够运行是由线程调度器决定的。start()调用并不表示相应线程已经开始运行,这个线程可能稍后运行。
创建并启动一个线程,真正实现了多线程。无需等待run()方法中的代码执行完毕,就可以接着执行下面的代码。此时start()的这个线程处于就绪状态,当得到CPU的时间片后就会执行其中的run()方法。这个run()方法包含了要执行的这个线程的内容,run()方法运行结束线程终止。

start()方法能够异步的调用run()方法,但是直接调用run()方法却是同步的,无法达到多线程的目的。因此,只用通过调用线程类的start()方法才能达到多线程的目的。

双重校验锁的单例模式

volatile修饰singleton很有必要,voliatile防止了指令重排

在这里插入代码片

volatile关键字

在现在的java模型下,线程可以把变量保存在本地内存(比如寄存器)中,而不是直接在主内存中进行读写,这就可能造成一个线程在主内存中修改了一个变量的值,而另外一个线程还继续使用它在寄存器中的变量的拷贝,造成数据不一致。

sychronized关键字

sychronized和volatile的区别

二 线程池

ThreadPoolExecutor

线程池的作用

在实践应用中创建线程池主要是为了:

  1. 减少资源开销:减少每次创建、销毁线程的开销;
  2. 提高响应速度:请求到来时,线程已创建好,可直接执行,提高响应速度;
  3. 提高线程的可管理性:线程是稀缺资源,需根据情况加以限制,确保系统稳定运行;

通过 Callable 和 Future 创建线程

1.创建 Callable 接口的实现类,并实现 call() 方法,该 call() 方法将作为线程执行体,并且有返回值。
2.创建 Callable 实现类的实例,使用 FutureTask 类来包装 Callable 对象,该 FutureTask 对象封装了该 Callable 对象的 call() 方法的返回值。
3.使用 FutureTask 对象作为 Thread 对象的 target 创建并启动新线程。
4.调用 FutureTask 对象的 get() 方法来获得子线程执行结束后的返回值。

实现Runnable和Callable接口的区别

https://www.jianshu.com/p/27b7340d8470

参考资料

Java中的多线程
https://www.cnblogs.com/wxd0108/p/5479442.html

volatile的设计原理
https://mp.weixin.qq.com/s/WTqdSz-lc5zzelJgk4Co8g

ThreadPoolExecutor
https://mp.weixin.qq.com/s/ROQMBFw0DWM4sSP-sdy-IA

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java多线程线程池是一种重用线程的机制,它可以管理和调度多个线程来执行任务。使用线程池可以提高程序的性能和效率,同时也可以避免线程的频繁创建和销毁。 在Java中,可以使用线程池类ExecutorService和Executors来创建和管理线程池。具体步骤如下: 1. 创建一个线程池对象:可以使用Executors提供的静态方法创建不同类型的线程池,比如newFixedThreadPool固定大小线程池、newCachedThreadPool缓存线程池等。 2. 向线程池提交任务:使用submit方法向线程池提交需要执行的任务,也可以使用execute方法提交任务。任务可以是实现了Runnable接口或Callable接口的类,也可以是Lambda表达式。 3. 线程池执行任务:线程池会根据线程池的规模和任务的数量来调度和执行任务,多个任务会并发执行。 4. 关闭线程池:当不再需要线程池时,可以调用线程池的shutdown方法来关闭线程池,确保所有的任务都被执行完毕。 使用线程池的好处有: 1. 提高性能:线程池可以重用线程,避免线程频繁创建和销毁的开销,提高程序的性能。 2. 提供线程管理和调度:线程池可以管理和调度线程,根据线程池的规模和任务的数量来调度和执行任务。 3. 控制资源的使用:线程池可以限制并发线程的数量,避免过度占用系统资源。 在Java开发中,使用线程池是一种推荐的多线程编程方式,也是阿里巴巴在其《Java开发手册》中强制规定的做法。 Java线程的创建是依赖于系统内核的,通过JVM调用系统库创建内核线程,内核线程与Java Thread是1:1的映射关系。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [Java多线程(六):线程池详解](https://blog.csdn.net/m0_59140023/article/details/124436385)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *3* [java多线程线程池](https://blog.csdn.net/qq_29996285/article/details/118955325)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值