Java 中的线程池
在多线程并发的环境下创建多个线程去执行任务,每当有一个任务到来的时候都需要创建一个线程去执行。这种方式虽然是可行的,但如果线程并发的数量很多,并且每个线程都是执行一个时间很短的任务就结束掉了,这样频繁的创建线程就会大大降低系统的运行效率,因为频繁的创建和销毁线程需要消耗额外的时间。对于这种情况,我们可以使用线程池技术让线程达到复用的目的。
在多线程并发的环境下创建多个线程去执行任务,每当有一个任务到来的时候都需要创建一个线程去执行。这种方式虽然是可行的,但如果线程并发的数量很多,并且每个线程都是执行一个时间很短的任务就结束掉了,这样频繁的创建线程就会大大降低系统的运行效率,因为频繁的创建和销毁线程需要消耗额外的时间。对于这种情况,我们可以使用线程池技术让线程达到复用的目的。
使用 Java 中的 ThreadLocal 类可以创建只能由同一个线程读写的变量。也就是说,即使两个线程在执行相同的代码,并且代码中都有对同一个 ThreadLocal 变量的引用,那么这两个线程也不会看到对方的 ThreadLocal 变量。因此,Java 中的 ThreadLocal 类提供了一种简单的方式来使代码中的线程变得更加安全。
之前的文章,比如在多线程环境中使用 synchronized 和 Lock 可以通过锁的方式实现线程之间的同步互斥访问临界资源。也就是说,只有当一个线程释放了锁之后,另一个线程才能获得锁,从而对数据进行操作。但在有些情况下,需要多个线程之间进行协作,以使得多个线程可以一起去解决某个问题,此时就需要采用线程通信-协作机制。
上节 《Java 中的 synchronized》介绍了能够在多线程访问临界资源的情况下,使用 synchronized 关键字可以保证线程之间的顺序执行(序列化访问临界资源),即同一时刻只能由一个线程获得当前对象的锁。可以看到 synchronized 是在 JVM 层面实现了对临界资源的同步互斥访问,但锁的粒度较大。本文将介绍并发包下的 Lock 接口,同样也可以实现锁的功能。
在多线程并发的情况下,多线程同时访问的资源叫做临界资源(如变量、对象、文件等),当多个线程同时访问对象并要求操作相同资源时,其操作可能存在数据不一致或数据不完整的情况。为了避免这种情况的发生,需要采取同步互斥机制,以确保在某一时刻,方法内只允许一个线程对该资源进行操作,而其它线程只能等待。
ConcurrentHashMap 是 HashMap 的一个线程安全并且支持高并发的版本,之前的文章《Java 容器之 HashMap》从 HashMap 的实现原理到各个方法的使用,以及每个方法各自的具体实现都分别进行了介绍,并将 JDK1.7 与 JDK1.8 中的 HashMap 进行了对比。
当在 Java 中创建对象的时候,只要我们需要这个对象,它就会一直存在。但是一旦程序终止,它们也就不复存在了。如果我们想让对象能够在程序不运行的状态下仍然能够保存它们的信息,那就需要用到序列化机制
。
本文主要介绍 Thread 类中线程的六种状态以及各状态之间转换的方法,如 wait()、start()、run()、sleep() 等。在阐述线程的生命周期的同时,解释各个方法是如何使线程的状态进行转换的,以及在转换的过程中是否需要释放锁等问题。