线程的三大特性:原子性、可见性、有序性。
线程的优势
常见的例子
线程的风险
安全性问题
当2个线程同时读取一个值value时,会导致不可预料的结果。eg: 两个线程同时读取序列生成器时,会出现两个线程相同值的情况。发生这种问题的情况,叫做竞态条件。需要使用java中的同步机制来解决这一问题。
活跃性问题
当程序占用一个资源,一直不释放时。其他的线程活跃性就较低。
eg:死锁、活锁、饥饿。
性能问题
上下文的切换等。
💡几乎所有的java程序都是多线程的。
使用多线程的场景
-
提高性能: 多线程可以利用多核处理器的优势,同时执行多个任务,从而提高程序的整体性能和响应速度。例如,对于需要大量计算或者IO操作的程序,可以通过多线程并发执行来加快处理速度。
-
提高资源利用率: 多线程可以更有效地利用系统资源,包括CPU、内存、网络和磁盘等。通过合理地组织线程,可以使得系统的资源利用率更加高效。
-
实现异步操作: 多线程可以实现异步编程模型,允许程序在等待某些操作完成的同时继续执行其他任务。这对于需要与外部系统交互或者处理IO密集型任务的程序来说非常有用。
-
交互性和响应性: 在图形用户界面(GUI)应用程序中,多线程可以用来处理用户输入、界面刷新等任务,从而提高程序的交互性和响应性。通过将耗时的任务放在单独的线程中执行,可以确保界面保持流畅响应,不会因为阻塞而导致用户体验下降。
-
并发处理: 在服务器端应用程序中,多线程可以用来处理并发访问请求,允许多个客户端同时与服务器进行交互。这样可以提高服务器的处理能力和吞吐量,更好地满足大量用户的需求。
💡茶壶、微波炉的生厂商都很清楚,他们的用户会使用异步的方式使用,所以当做好饭时会有提示音。
💡总结的话就是两点:解决的是:
单位时间内的吞吐量问题
、响应速率问题
。什么是线程安全性?
当多个线程访问某个类时,这个类
始终都能表现出正确的行为
,那么就称这个类是线程安全的
。
不可变的对象不存在线程安全问题,编写线程安全的代码核心是对共享的(shared)
和可变的(Mutable)
的状访问。
[[08.状态、实例变量、参数、封装!]] 类变量、成员变量、受并发影响的内部状态。/** * 类变量 */ private static int a;
/**
* 成员变量
*/
private int b;
# 所有的Java程序都是多线程的!
- main
: 主线程
- Reference Handler
: 处理引用对象本身(软、弱、虚引用)的线程
- Finalizer
: 调用对象的finalize方法的线程,也就是说垃圾回收的守护线程
- Signal Dispatcher
: 接受处理各种信号的线程
- Attach Listener
: 监听各种请求的socket连接,把执行的操作扔给VM Thread的线程
- VM Thread
: 线程母体,最原始的线程,单例,里面有个队列,存放上面的操作,它负责loop处理队列中的操作(包括对其他线程的创建,分配和对象的清理,cms-mark等工作)
- CompilerThread0
: JIT动态编译线程
- ConcurrentMark-SweepGCThread
: CMS垃圾收集线程
- DestroyJavaVM
: 负责卸载JVM的线程
- ContainerBackground Processor
: JBoss守护线程
- Dispatcher-Thread-3
: Log4j异步日志守护线程
- Gang worker#0
: 新生代回收线程
- GC Daemon
: RMI远程GC线程(调用system.gc())
- Low MemoryDetector
: 发现可用内存低,则分配新的内存空间
- Process reaper
: 执行os命令的线程
- SurrogateLockerThread
: CMS垃圾回收
- VM Periodic Task Thread
: 定期的内存监控、JVM运行状况监控