Thread Synchronization Java 线程同步

合集下载

java 保证线程间同步的方法

java 保证线程间同步的方法

java 保证线程间同步的方法Java保证线程间同步的方法介绍在多线程的应用中,保证线程间同步以避免竞态条件是非常重要的。

Java提供了多种方法来实现线程间同步,本文将详细介绍这些方法。

1. 使用synchronized关键字synchronized是Java中最基本的保证线程同步的方法。

它可以用来修饰方法或代码块,确保在同一时间只有一个线程可以访问被synchronized修饰的代码。

2. 使用volatile关键字volatile关键字可以用来保证变量的可见性和有序性,并禁止指令重排序。

它适用于对变量的写操作不依赖于当前值的场景。

3. 使用Lock接口Lock接口提供了更灵活和可扩展的线程同步机制。

它包含了lock()和unlock()方法,分别用于获取和释放锁。

与synchronized 关键字相比,Lock接口提供了更多的功能,如可重入锁、公平锁等。

4. 使用Semaphore信号量Semaphore是一个计数信号量,用来控制同时访问某个资源的线程数量。

通过控制信号量的许可数量,可以限制同时执行的线程数量,从而实现线程同步。

5. 使用CountDownLatch倒计时器CountDownLatch提供了一种简单而有效的方式来等待一组线程完成任务。

它通过一个计数器来控制线程的等待,当计数器减到零时,等待的线程就可以继续执行。

6. 使用CyclicBarrier循环屏障CyclicBarrier可以用于多个线程之间相互等待,直到所有线程都到达某个屏障点。

一旦所有线程都达到屏障点,屏障将被触发,所有线程可以继续执行。

7. 使用Condition条件Condition接口提供了更灵活精确的线程间通信方式。

它可以让线程在某个条件满足时等待,或者在某个条件满足时唤醒等待的线程。

8. 使用ReadWriteLock读写锁ReadWriteLock接口提供了读写分离锁,可以加快读操作的速度。

它允许多个线程同时读取共享资源,但只允许一个线程进行写操作。

java语言的线程同步方法

java语言的线程同步方法

java语言的线程同步方法1.引言【1.1 概述】在多线程编程中,线程同步是一项重要的技术,它可以确保多个线程在访问共享资源时的正确性和安全性。

在并发编程中,当多个线程同时访问共享资源时,可能会出现数据竞争、死锁等问题。

为了解决这些问题,Java提供了一些线程同步方法,以保证多线程程序的正确执行。

线程同步方法可以确保线程在访问共享资源时的互斥性,即同一时刻只有一个线程可以访问共享资源。

通过使用锁机制或volatile变量等机制,Java提供了多种方法来实现线程的同步。

这些方法包括synchronized关键字、Lock接口及其实现类、volatile关键字等。

通过使用这些线程同步方法,开发人员可以避免多线程程序中常见的问题,如数据不一致、死锁、竞态条件等。

同时,线程同步方法可以提高多线程程序的性能和效率,使得多个线程可以并发地执行,从而充分发挥多核处理器的性能优势。

在本文中,我们将探讨Java语言中的线程同步方法。

我们将介绍线程同步的概念和重要性,以及Java中提供的线程同步方法。

我们还将总结线程同步方法的作用和优势,并展望它们在未来的发展前景。

下面我们将详细介绍Java中的线程同步方法,以帮助读者更好地理解和应用这些方法。

1.2文章结构1.2 文章结构本文将围绕着Java语言中线程同步的概念和方法展开讨论。

文章主要分为三个部分:引言、正文和结论。

引言部分将对本文所讨论的主题进行概述,介绍线程同步的概念及其重要性,并阐明文章的目的。

正文部分将详细探讨Java语言中的线程同步方法。

首先,将对线程同步的概念和重要性进行深入解释,说明为什么在多线程环境下需要进行线程同步。

然后,将介绍Java语言中提供的线程同步方法,包括synchronized关键字、Lock接口及其实现类、volatile关键字等,对每种方式的使用方法、应用场景和注意事项进行详细说明和比较分析。

结论部分将总结线程同步方法的作用和优势,强调线程同步在多线程编程中的重要性。

Java线程同步机制:synchronized关键字详解

Java线程同步机制:synchronized关键字详解

Java线程同步机制:synchronized关键字详解在Java编程中,多线程是一种非常重要的编程模型。

当多个线程同时访问共享资源时,可能会导致数据不一致或者并发访问的错误。

为了解决这个问题,在Java中提供了一些同步机制来确保多个线程之间的协调和同步。

什么是线程同步线程同步是指多个线程在访问共享资源时,对资源的操作按照一定的顺序进行,从而避免出现数据不一致或者并发访问的错误。

在Java中,可以通过同步机制来实现线程同步。

synchronized关键字在Java中,可以使用synchronized关键字来实现同步。

synchronized关键字可以用来修饰方法或者代码块,以确保多个线程之间的安全访问共享资源。

synchronized修饰方法public synchronized void doSomething(){// 在这里进行操作}当一个线程访问一个synchronized修饰的方法时,其他线程必须等待该线程执行完成才能继续访问该方法。

synchronized修饰代码块public void doAnotherThing(){synchronized(this){// 在这里进行操作}}当一个线程访问一个synchronized块时,其他线程也必须等待当前线程执行完成才能继续访问。

synchronized关键字的使用场景synchronized关键字可以确保多个线程在访问共享资源时按照一定的顺序进行操作,从而避免数据不一致或者并发访问的错误。

通常情况下,synchronized关键字常用于以下场景:•多个线程访问共享资源•多个线程需要互斥执行某些操作•需要保证操作的原子性总结在Java中,synchronized关键字是实现线程同步的重要机制之一。

通过synchronized关键字,可以确保多个线程在访问共享资源时按照一定的顺序进行操作,从而避免数据不一致或者并发访问的错误。

合理使用synchronized关键字可以帮助我们编写出更加安全和可靠的多线程程序。

java并发之线程同步(synchronized和锁机制)

java并发之线程同步(synchronized和锁机制)

java并发之线程同步(synchronized和锁机制)多个执⾏线程共享⼀个资源的情景,是并发编程中最常见的情景之⼀。

多个线程读或者写相同的数据等情况时可能会导致数据不⼀致。

为了解决这些问题,引⼊了临界区概念。

临界区是⼀个⽤以访问共享资源的代码块,这个代码块在同⼀时间内只允许⼀个线程执⾏。

Java提供了同步机制。

当⼀个线程试图访问⼀个临界区时,它将使⽤⼀种同步机制来查看是不是已有其他线程进⼊临界区。

如果没有其他线程进⼊临界区,它就可以进⼊临界区;如果已有线程进⼊了临界区,它就被同步机制挂起,直到进⼊的线程离开这个临界区。

如果在等待进⼊临界区的线程不⽌⼀个,JVM会随机选择其中的⼀个,其余的将继续等待。

概念⽐较好理解,具体在java程序中是如何体现的呢?临界区对应的代码是怎么样的?使⽤synchronized实现同步⽅法每⼀个⽤synchronized关键字声明的⽅法都是临界区。

在Java中,同⼀个对象的临界区,在同⼀时间只有⼀个允许被访问。

注意:⽤synchronized关键字声明的静态⽅法,同时只能被⼀个执⾏线程访问,但是其他线程可以访问这个对象的⾮静态⽅法。

即:两个线程可以同时访问⼀个对象的两个不同的synchronized⽅法,其中⼀个是静态⽅法,⼀个是⾮静态⽅法。

知道了synchronized关键字的作⽤,再来看⼀下synchronized关键字的使⽤⽅式。

在⽅法声明中加⼊synchronized关键字1public synchronized void addAmount(double amount) {2 }在代码块中使⽤synchronized关键字,obj⼀般可以使⽤this关键字表⽰本类对象1synchronized(obj){2 }需要注意的是:前⾯已经提到,引⼊synchronized关键字是为了声明临界区,解决在多线程环境下共享变量的数据更改安全问题。

那么,⼀般⽤到synchronized关键字的地⽅也就是在对共享数据访问或者修改的地⽅。

java线程同步的方法

java线程同步的方法

java线程同步的方法Java是一门面向对象的编程语言,而线程同步则是在并发编程中非常重要的一部分。

在Java中,我们有许多方法可以实现线程同步。

本文将介绍一些基本的Java线程同步方法。

一、synchronized关键字synchronized关键字是Java最基本的线程同步方法。

在Java中,只有一个线程可以访问同步块或同步方法。

这种方法可以避免竞态条件,以及多线程之间的数据冲突。

二、Lock接口Lock接口是一个更加灵活的线程同步方法。

与synchronized关键字不同的是,Lock接口需要通过调用lock()方法来获取锁,unlock()方法来释放锁。

这种方法比synchronized关键字更加灵活,可以在使用时指定获取锁的超时时间等参数。

三、使用Atomic变量Atomic变量是Java中提供的一种线程安全的变量类型。

多个线程可以同时访问Atomic变量,而不会出现数据冲突的情况。

在Java中,有多种类型的Atomic变量可以选择,比如AtomicInteger、AtomicBoolean和AtomicReference等。

四、SemaphoreSemaphore是一种控制并发访问的同步工具。

它可以用于控制在某一时刻内有多少线程能够访问某个资源。

这种同步工具可以指定可以访问资源的线程数目,同时可以在使用完成后释放资源,以便其他线程可以继续使用。

五、CountDownLatchCountDownLatch是一种同步工具,可以用于等待一组线程的完成。

在CountDownLatch中,初始时可以指定需要等待的线程数,每个线程完成后将计数器减一。

当计数器减为0时,等待的线程就可以继续执行。

这种同步工具通常被用于等待多个子线程完成后,再进行后续的操作。

六、CyclicBarrierCyclicBarrier是一种同步工具,可以等待一组线程达到一个屏障点。

在CyclicBarrier中,当达到预定数目的线程后,所有的线程将被释放并可以继续执行。

java中线程同步的几种方法

java中线程同步的几种方法

java中线程同步的几种方法在Java中,线程同步是一种确保多个线程可以安全地访问共享资源的方法。

以下是Java中实现线程同步的几种方法:1. synchronized关键字:这是最基本的方法,通过在方法或代码块前加上synchronized关键字实现。

当一个线程进入一个synchronized方法或代码块时,会获取一个锁,其他线程必须等待该锁被释放后才能进入。

2. 使用ReentrantLock:Java的包中提供了更高级的线程同步工具,其中最常用的是ReentrantLock。

ReentrantLock提供了比synchronized更灵活的锁定机制,包括尝试获取锁、定时获取锁、中断获取锁等。

3. 使用Semaphore:Semaphore是一种计数信号量,可以控制同时访问共享资源的线程数量。

当一个线程需要访问资源时,会尝试获取信号量,如果信号量值为0,则线程会被阻塞,等待其他线程释放信号量。

4. 使用CountDownLatch:CountDownLatch是一个同步辅助类,允许一个或多个线程等待其他线程完成操作。

它有一个计数器,初始化为一个正数,每次调用countDown()方法计数器减1,当计数器达到0时,所有等待的线程被唤醒。

5. 使用CyclicBarrier:CyclicBarrier是一个同步辅助类,允许一组线程互相等待,直到所有线程都到达某个状态后再一起继续执行。

通常用于并行计算中,当所有线程完成某个任务后一起开始下一个任务。

6. 使用Phaser:Phaser是Java 7引入的一个同步辅助类,类似于CyclicBarrier,但功能更强大。

它支持多阶段同步,可以在不同阶段让不同数量的线程通过。

以上是Java中实现线程同步的几种方法,根据具体需求选择合适的方法可以提高程序的效率和安全性。

Java程序设计中的线程同步与线程池实现案例

Java程序设计中的线程同步与线程池实现案例

Java程序设计中的线程同步与线程池实现案例在Java程序设计中,线程同步和线程池的实现是非常重要的概念。

线程同步用于保证多个线程之间的数据一致性和安全性,而线程池则用于提高线程的执行效率和资源利用率。

本文将结合实例来讨论线程同步与线程池的概念、实现方式及其在Java程序设计中的应用。

一、线程同步的概念与实现方式线程同步是指多个线程在访问共享资源时的一种机制,通过线程同步可以有效避免线程之间的数据竞争、死锁等问题,确保数据的正确性和线程的安全运行。

常见的线程同步实现方式包括使用synchronized关键字和使用Lock 接口。

synchronized关键字可以用于修饰方法或代码块,实现对共享资源的访问限制。

例如,以下代码演示了使用synchronized关键字实现线程同步的示例:```javapublic class ThreadSyncExample {private int count = 0;public synchronized void increment() {count++;}public synchronized void decrement() {count--;}public int getCount() {return count;}}```在上述示例中,使用synchronized修饰的方法实现了对共享资源count的访问控制,确保线程安全。

在多线程环境下,不同线程调用increment()和decrement()方法时,会依次执行,避免了数据竞争和不一致的问题。

另一种常见的线程同步方式是使用Lock接口,它提供了更灵活的线程同步控制。

以下是使用Lock接口实现线程同步的示例:```javaimport java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;public class ThreadSyncExample {private int count = 0;private Lock lock = new ReentrantLock();public void increment() { lock.lock();try {count++;} finally {lock.unlock();}}public void decrement() { lock.lock();try {count--;} finally {lock.unlock();}}public int getCount() {return count;}}```在上述示例中,通过使用ReentrantLock实现了对共享资源count的访问控制。

Java中的线程同步与并发控制方法

Java中的线程同步与并发控制方法

Java中的线程同步与并发控制方法随着计算机技术的发展,多核处理器的出现使得并发编程变得越来越重要。

在Java中,线程同步与并发控制方法是实现多线程程序的关键。

本文将探讨Java中常用的线程同步与并发控制方法,帮助读者更好地理解和应用这些方法。

1. 互斥锁(Mutex)互斥锁是一种最常见的线程同步机制,用于控制对共享资源的访问。

在Java中,可以使用synchronized关键字来实现互斥锁。

当一个线程进入synchronized代码块时,其他线程将被阻塞,直到该线程执行完毕释放锁。

这种方式能够有效地防止多个线程同时访问共享资源,避免产生竞态条件和数据不一致的问题。

2. 信号量(Semaphore)信号量是一种用于控制并发访问资源的方法。

在Java中,可以使用Semaphore类来实现信号量。

信号量维护了一个计数器,表示可用资源的数量。

当一个线程需要访问资源时,首先尝试获取信号量。

如果信号量计数器大于0,则线程可以继续执行;否则,线程将被阻塞,直到有其他线程释放资源并增加信号量计数器。

3. 条件变量(Condition)条件变量是一种用于线程间通信的机制,允许线程在满足特定条件之前等待。

在Java中,可以使用Condition接口来实现条件变量。

通过调用Condition的await()方法,线程可以进入等待状态,直到其他线程调用该Condition的signal()或signalAll()方法唤醒它们。

条件变量常用于生产者-消费者问题等场景中。

4. 读写锁(ReadWriteLock)读写锁是一种用于控制读写操作的机制,允许多个线程同时读取共享资源,但只允许一个线程进行写操作。

在Java中,可以使用ReentrantReadWriteLock类来实现读写锁。

读写锁分为读锁和写锁两种,当读锁被获取时,其他线程可以继续获取读锁,但不能获取写锁;当写锁被获取时,其他线程无法获取读锁或写锁,直到写锁被释放。

java中接口并发的一般处理方案

java中接口并发的一般处理方案

java中接口并发的一般处理方案在Java中处理接口并发问题,通常有几种常见的策略:1. 同步块(Synchronization):使用`synchronized`关键字,可以确保在任何时刻只有一个线程可以执行特定代码块。

这对于防止数据竞争和资源争用是非常有用的。

但是,需要注意的是,同步会影响性能,并可能在过度使用时导致死锁。

2. 线程池(Thread Pools):使用线程池可以更有效地管理线程。

通过预先创建一组线程,并在需要时将任务分配给这些线程,可以避免频繁地创建和销毁线程,从而提高性能。

Java的``包提供了多种线程池实现,如`ExecutorService`和`ForkJoinPool`。

3. 并发集合(Concurrent Collections):Java的并发包提供了多种线程安全的集合类,如`ConcurrentHashMap`和`CopyOnWriteArrayList`。

这些集合类内部使用了各种同步机制,可以在多线程环境中安全地使用。

4. 信号量(Semaphores):使用信号量可以控制对共享资源的访问。

信号量是一个计数器,可以用来保护代码块或资源,确保在任何时刻只有一个线程可以访问它们。

5. 乐观锁(Optimistic Locking):在并发环境中,乐观锁假设冲突不会频繁发生。

它通常通过在数据更新时检查版本号或时间戳来实现。

如果检测到冲突,则更新会失败,并需要重新尝试。

6. 悲观锁(Pessimistic Locking):与乐观锁相反,悲观锁假设冲突会频繁发生,因此在访问数据时会立即锁定数据。

其他线程必须等待锁释放后才能访问数据。

以上是处理Java接口并发问题的一些常见策略。

具体使用哪种方案取决于具体的应用场景和需求。

java 线程同步的

java 线程同步的

java 线程同步的Java是一种面向对象的编程语言,它支持多线程编程。

在多线程编程中,线程同步是一个重要的概念。

本文将介绍Java中线程同步的概念、原因和实现方法。

线程同步是指多个线程按照一定的顺序执行,以避免数据竞争和不确定性的结果。

在并发编程中,多个线程同时访问共享资源时,可能会造成数据不一致的问题。

线程同步就是为了解决这个问题而引入的机制。

为什么需要线程同步呢?在多线程环境下,多个线程可以同时访问和修改共享资源。

如果不进行线程同步,可能会导致数据的不一致性。

例如,一个线程正在修改一个变量的值,而另一个线程正在读取该变量的值,由于读写操作的不确定性,可能会导致读取到错误的值。

因此,为了保证数据的一致性,我们需要使用线程同步机制。

在Java中,线程同步可以通过多种方式实现。

最常用的方式是使用synchronized关键字。

synchronized关键字可以用来修饰方法和代码块。

当一个线程访问一个带有synchronized关键字修饰的方法或者代码块时,其他线程必须等待该线程释放锁才能继续执行。

除了synchronized关键字,Java还提供了其他的线程同步机制,例如ReentrantLock和Semaphore。

ReentrantLock是一个可重入的互斥锁,它提供了更灵活的锁机制。

Semaphore是一个计数信号量,它可以用来控制对共享资源的访问。

在使用线程同步时,需要注意一些问题。

首先,要避免死锁的发生。

死锁是指两个或多个线程互相等待对方释放锁,导致程序无法继续执行的情况。

为了避免死锁,我们需要合理地设计线程同步机制。

其次,要避免过多地使用锁,以提高程序的并发性能。

锁的获取和释放都需要消耗一定的系统资源,过多地使用锁可能会导致性能下降。

在多线程编程中,还需要考虑线程的安全性。

线程的安全性是指多个线程同时访问共享资源时,不会发生不确定的结果。

为了保证线程的安全性,我们可以使用线程安全的数据结构或者加锁机制。

java线程同步方法

java线程同步方法

java线程同步方法
Java线程同步方法是一种可以保证多个线程在访问共享资源时不会产生冲突的技术。

在多线程编程中,当多个线程同时访问同一个对象的方法时,可能会发生数据不一致或者程序崩溃的情况。

为了解决这个问题,我们可以使用Java线程同步方法。

Java线程同步方法的原理是使用synchronized关键字来限制同时只能有一个线程访问该方法。

当一个线程正在执行synchronized 方法时,其他线程需要等待这个线程执行完毕后才能访问该方法。

这样就能保证多个线程不会同时访问同一份数据而导致冲突。

除了使用synchronized关键字,Java还提供了其他一些同步方法,例如使用Lock对象、使用Semaphore信号量、使用CountDownLatch 倒数计时器等。

这些同步方法都能够有效地保证多线程访问共享资源时的安全性和正确性。

总之,Java线程同步方法是一种非常重要的技术,它能够帮助我们解决多线程并发访问共享资源时可能会产生的问题,确保程序的正确性和稳定性。

- 1 -。

JAVA-线程同步和线程调度的相关方法

JAVA-线程同步和线程调度的相关方法

JAVA-线程同步和线程调度的相关⽅法JAVA - 线程同步和线程调度的相关⽅法wait():使⼀个线程处于等待(阻塞)状态,并且释放所持有的对象的锁;wait是Object类的⽅法,对此对象调⽤wait⽅法导致本线程放弃对象锁,进⼊等待此对象的等待锁定池,只有针对此对象发出notify⽅法(或notifyAll)后本线程才进⼊对象锁定池准备获得对象锁进⼊运⾏状态。

sleep():使⼀个正在运⾏的线程处于睡眠状态,是⼀个静态⽅法,调⽤此⽅法要处理InterruptedException异常;sleep是线程类(Thread)的⽅法,导致此线程暂停执⾏指定时间,把执⾏机会给其他线程,但是监控状态依然保持,到时后会⾃动恢复。

调⽤sleep 不会释放对象锁。

notify():唤醒⼀个处于等待状态的线程,当然在调⽤此⽅法的时候,并不能确切地唤醒某⼀个等待状态的线程,⽽是由JVM确定唤醒哪个线程,⽽且与优先级⽆关;notityAll():唤醒所有处于等待状态的线程,该⽅法并不是将对象的锁给所有线程,⽽是让它们竞争,只有获得锁的线程才能进⼊就绪状态;通过Lock接⼝提供了显式的锁机制(explicit lock),增强了灵活性以及对线程的协调。

Lock接⼝中定义了加锁(lock())和解锁(unlock())的⽅法,同时还提供了newCondition()⽅法来产⽣⽤于线程之间通信的Condition对象;此外,Java 5还提供了信号量机制(semaphore),信号量可以⽤来限制对某个共享资源进⾏访问的线程的数量。

在对资源进⾏访问之前,线程必须得到信号量的许可(调⽤Semaphore对象的acquire()⽅法);在完成对资源的访问后,线程必须向信号量归还许可(调⽤Semaphore对象的release()⽅法)。

java线程间同步的几种方法

java线程间同步的几种方法

java线程间同步的几种方法以Java线程间同步的几种方法为标题,本文将介绍Java中常用的几种线程同步方法,包括synchronized关键字、Lock接口、Semaphore信号量、CountDownLatch倒计时门栓和CyclicBarrier循环屏障。

1. synchronized关键字synchronized关键字是Java中最常用的线程同步方法之一。

它可以修饰方法或代码块,确保同一时间只有一个线程可以访问被修饰的代码段。

使用synchronized关键字可以保证线程的安全性,避免多个线程同时访问共享资源导致的数据不一致问题。

2. Lock接口Lock接口是Java中提供的另一种线程同步方法。

与synchronized 关键字不同,Lock接口提供了更细粒度的控制,可以实现更灵活的线程同步机制。

Lock接口的实现类ReentrantLock可以实现公平锁或非公平锁的选择,并且可以实现可重入锁的功能。

3. Semaphore信号量Semaphore信号量是一种更为复杂的线程同步方法,它可以控制同时访问某个资源的线程数量。

Semaphore维护了一个计数器,表示可用的许可证数量。

当一个线程想要访问共享资源时,它必须先获取一个许可证,如果没有许可证可用,线程将被阻塞直到有许可证可用。

当线程使用完共享资源后,需要释放许可证,以方便其他线程访问。

4. CountDownLatch倒计时门栓CountDownLatch是一种线程同步辅助类,它可以让一个或多个线程等待其他线程完成操作后再继续执行。

CountDownLatch内部有一个计数器,当计数器的值为0时,等待的线程将被唤醒。

每个线程执行完任务后可以调用countDown()方法来使计数器减1,当计数器的值减为0时,等待的线程将被唤醒。

5. CyclicBarrier循环屏障CyclicBarrier也是一种线程同步辅助类,它可以让一组线程相互等待,直到所有线程都达到某个屏障点后再继续执行。

Thread Snychronization线程同步

Thread Snychronization线程同步

线程的同步Critical section(临界区)用来实现“排他性占有”。

适用范围是单一进程的各线程之间。

它是:·一个局部性对象,不是一个核心对象。

·快速而有效率。

·不能够同时有一个以上的critical section被等待。

·无法侦测是否已被某个线程放弃。

MutexMutex是一个核心对象,可以在不同的线程之间实现“排他性占有”,甚至几十那些现成分属不同进程。

它是:·一个核心对象。

·如果拥有mutex的那个线程结束,则会产生一个“abandoned”错误信息。

·可以使用Wait…()等待一个mutex。

·可以具名,因此可以被其他进程开启。

·只能被拥有它的那个线程释放(released)。

SemaphoreSemaphore被用来追踪有限的资源。

它是:·一个核心对象。

·没有拥有者。

·可以具名,因此可以被其他进程开启。

·可以被任何一个线程释放(released)。

Event ObjectEvent object通常使用于overlapped I/O,或用来设计某些自定义的同步对象。

它是:·一个核心对象。

·完全在程序掌控之下。

·适用于设计新的同步对象。

·“要求苏醒”的请求并不会被储存起来,可能会遗失掉。

·可以具名,因此可以被其他进程开启。

Interlocked Variable如果Interlocked…()函数被使用于所谓的spin-lock,那么他们只是一种同步机制。

所谓spin-lock是一种busy loop,被预期在极短时间内执行,所以有最小的额外负担(overhead)。

系统核心偶尔会使用他们。

除此之外,interlocked variables主要用于引用技术。

他们:·允许对4字节的数值有些基本的同步操作,不需动用到critical section或mutex 之类。

Java多线程编程中的线程同步与锁技术

Java多线程编程中的线程同步与锁技术

Java多线程编程中的线程同步与锁技术多线程编程是Java中的重要特性之一,它可以让程序同时执行多个任务,提高程序的运行效率。

然而,在多线程环境下,多个线程同时修改共享资源可能会导致数据的不一致性或者错误的结果。

为了解决这个问题,在Java中引入了线程同步和锁技术。

第一章:线程同步的概念线程同步是指多个线程按照一定的顺序来访问共享资源。

在Java中,使用synchronized关键字来实现线程同步。

synchronized 关键字可以修饰方法或者代码块,当某个线程执行到带有synchronized修饰的方法或者代码块时,会获得该方法或者代码块的锁,其他线程必须等待该线程执行完毕释放锁之后才能继续执行。

第二章:对象锁和类锁在Java中,每个对象都有一个与之关联的锁,这个锁也称为对象锁。

当一个线程获取了某个对象的锁之后,其他线程就不能访问该对象的其他同步方法或者代码块,只能等待该线程释放锁。

另外,还有一种特殊的锁,称为类锁,它是被所有对象所共享的锁。

第三章:使用synchronized关键字实现线程同步通过在方法前面加上synchronized关键字来实现线程同步是一种简单有效的方式。

当某个线程进入该方法时,会获取该方法所属对象的锁,其他线程必须等待该线程执行完毕之后才能执行。

第四章:使用synchronized代码块除了修饰方法,synchronized关键字还可以用于修饰代码块。

通过在代码块前面加上synchronized关键字,并指定一个对象作为锁,可以实现线程同步。

当一个线程进入该代码块时,会获取指定对象的锁,其他线程必须等待该线程执行完毕之后才能执行。

第五章:使用volatile关键字保证可见性在多线程环境下,当一个线程修改了共享资源的值之后,其他线程可能无法及时看到这个修改。

为了解决这个问题,可以使用volatile关键字。

volatile关键字可以保证对一个变量的写操作可见性,即当一个线程修改了该变量的值之后,其他线程可以立即看到这个修改。

线程同步synchronized同步代码块同步方法同步锁

线程同步synchronized同步代码块同步方法同步锁

线程同步synchronized同步代码块同步⽅法同步锁⼀同步代码块1.为了解决并发操作可能造成的异常,java的多线程⽀持引⼊了同步监视器来解决这个问题,使⽤同步监视器的通⽤⽅法就是同步代码块。

其语法如下:synchronized(obj){//同步代码块}其中obj就是同步监视器,它的含义是:线程开始执⾏同步代码块之前,必须先获得对同步监视器的锁定。

任何时刻只能有⼀个线程可以获得对同步监视器的锁定,当同步代码块执⾏完成后,该线程会释放对该同步监视器的锁定。

虽然java程序允许使⽤任何对象作为同步监视器,但是同步监视器的⽬的就是为了阻⽌两个线程对同⼀个共享资源进⾏并发访问,因此通常推荐使⽤可能被并发访问的共享资源充当同步监视器。

2.⼩例⼦Account.javapublic class Account {private String accountNo;private double balance;public Account(String accountNo,double balance){this.accountNo=accountNo;this.balance=balance;}public double getBalance() {return balance;}public void setBalance(double balance) {this.balance = balance;}public String getAccountNo() {return accountNo;}public void setAccountNo(String accountNo) {this.accountNo = accountNo;}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Account account = (Account) o;return accountNo.equals(account.accountNo);}@Overridepublic int hashCode() {return accountNo.hashCode();}}DrawThread.javapublic class DrawThread extends Thread {private Account account;private double drawAmount;public DrawThread(String name, Account account, double drawAmount) {super(name);this.account = account;this.drawAmount = drawAmount;}public void run(){synchronized (account){if(account.getBalance()>=drawAmount){System.out.println(getName() + "取钱成功,吐出钞票: " + drawAmount);try{Thread.sleep(1);}catch(InterruptedException ex){ex.getStackTrace();}account.setBalance(account.getBalance()-drawAmount);System.out.println("\t余额为:"+account.getBalance());}else{System.out.println(getName()+"取钱失败,余额不⾜");}}}}DrawTest.javapublic class DrawTest {public static void main(String[] args){Account acct=new Account("1234567",1000);new DrawThread("甲",acct,800).start();new DrawThread("⼄",acct,800).start();}}甲取钱成功,吐出钞票: 800.0余额为:200.0⼄取钱失败,余额不⾜3.如果将DrawThread的同步去掉:public class DrawThread extends Thread {private Account account;private double drawAmount;public DrawThread(String name, Account account, double drawAmount) {super(name);this.account = account;this.drawAmount = drawAmount;}public void run(){// synchronized (account){if(account.getBalance()>=drawAmount){System.out.println(getName() + "取钱成功,吐出钞票: " + drawAmount);try{Thread.sleep(1);}catch(InterruptedException ex){ex.getStackTrace();}account.setBalance(account.getBalance()-drawAmount);System.out.println("\t余额为:"+account.getBalance());}else{System.out.println(getName()+"取钱失败,余额不⾜");}// }}}会出现这些情况的结果:⼄取钱成功,吐出钞票: 800.0甲取钱成功,吐出钞票: 800.0余额为:200.0余额为:-600.0甲取钱成功,吐出钞票: 800.0⼄取钱成功,吐出钞票: 800.0余额为:200.0余额为:200.0程序使⽤synchronized将run()⽅法⾥的⽅法体修改成同步代码块,同步监视器就是account对象,这样的做法符合“加锁-修改-释放锁”的逻辑,这样就可以保证并发线程在任⼀时刻只有⼀个线程进⼊修改共享资源的代码区。

java thread同步调用方法

java thread同步调用方法

Java Thread同步调用方法在Java中,线程(Thread)是一种轻量级的执行单元,允许程序一次执行多个任务。

在多线程编程中,我们经常需要处理线程的同步问题,以确保线程之间的安全访问共享资源。

本文将探讨Java中线程同步调用方法的技术和最佳实践。

一、线程间通信的需求在实际应用中,多个线程可能需要协同工作来完成某个任务。

一个线程需要等待另一个线程的结果,或者多个线程需要共享某个资源。

这就需要线程间的通信和同步。

二、同步调用的实现在Java中,有多种方法可以实现线程的同步调用,常见的包括synchronized关键字、ReentrantLock、CountDownLatch等。

1. synchronized关键字synchronized关键字是Java中最基本的同步机制,可以用来给方法或代码块加锁,以保证同一时间只有一个线程可以访问被锁定的资源。

例如:```public class SynchronizedExample {private int count = 0;public synchronized void increment() {count++;}}```2. ReentrantLockReentrantLock是Java.util.concurrent包中提供的一种锁机制,它提供了比synchronized更灵活的锁操作。

例如:```public class ReentrantLockExample {private final ReentrantLock lock = new ReentrantLock();private int count = 0;public void increment() {lock.lock();try {count++;} finally {lock.unlock();}}}```3. CountDownLatchCountDownLatch是Java.util.concurrent包中提供的一种倒计数器,可以用来实现线程等待其他线程完成某个操作。

java线程同步(7种方式)

java线程同步(7种方式)

关于线程同步(7种方式)为何要使用同步?java允许多线程并发控制,当多个线程同时操作一个可共享的资源变量时(如数据的增删改查),将会导致数据不准确,相互之间产生冲突,因此加入同步锁以避免在该线程没有完成操作之前,被其他线程的调用,从而保证了该变量的唯一性和准确性。

1.同步方法即有synchronized关键字修饰的方法。

由于java的每个对象都有一个内置锁,当用此关键字修饰方法时,内置锁会保护整个方法。

在调用该方法前,需要获得内置锁,否则就处于阻塞状态。

代码如:public synchronized void save(){}注: synchronized关键字也可以修饰静态方法,此时如果调用该静态方法,将会锁住整个类2.同步代码块即有synchronized关键字修饰的语句块。

被该关键字修饰的语句块会自动被加上内置锁,从而实现同步代码如:synchronized(object){}注:同步是一种高开销的操作,因此应该尽量减少同步的内容。

通常没有必要同步整个方法,使用synchronized代码块同步关键代码即可。

代码实例:package com.xhj.thread;/*** 线程同步的运用** @author XIEHEJUN**/public class SynchronizedThread {class Bank {private int account = 100;public int getAccount() {return account;}/*** 用同步方法实现** @param money*/public synchronized void save(int money) { account += money;}/*** 用同步代码块实现** @param money*/public void save1(int money) {synchronized (this) {account += money;}}}class NewThread implements Runnable { private Bank bank;public NewThread(Bank bank) {this.bank = bank;}@Overridepublic void run() {for (int i = 0; i < 10; i++) {// bank.save1(10);bank.save(10);System.out.println(i + "账户余额为:" + bank.getAccount()); }}}/*** 建立线程,调用内部类*/public void useThread() {Bank bank = new Bank();NewThread new_thread = new NewThread(bank);System.out.println("线程1");Thread thread1 = new Thread(new_thread);thread1.start();System.out.println("线程2");Thread thread2 = new Thread(new_thread);thread2.start();}public static void main(String[] args) {SynchronizedThread st = new SynchronizedThread();eThread();}}3.使用特殊域变量(volatile)实现线程同步a.volatile关键字为域变量的访问提供了一种免锁机制,b.使用volatile修饰域相当于告诉虚拟机该域可能会被其他线程更新,c.因此每次使用该域就要重新计算,而不是使用寄存器中的值d.volatile不会提供任何原子操作,它也不能用来修饰final类型的变量例如:在上面的例子当中,只需在account前面加上volatile修饰,即可实现线程同步。

线程synchronized用法

线程synchronized用法

线程synchronized用法
线程synchronized用法是Java中常用的同步机制。

在多线程环境下,synchronized可以保证在同一时刻只有一个线程可以执行代码块或方法。

这种同步机制可以避免多线程环境下的数据竞争和数据不一致问题。

在使用synchronized时,需要注意以下几点:
1. 使用synchronized来保护共享数据,以避免多个线程同时修改同一数据。

2. 对于静态方法,可以使用synchronized修饰整个方法,也可以使用synchronized修饰该方法所属的类。

3. 对于非静态方法,可以使用synchronized修饰整个方法,也可以使用synchronized修饰该方法所属的对象。

4. 对于代码块,可以使用synchronized修饰代码块,以避免多个线程同时访问该代码块中的代码。

5. 在使用synchronized时,需要注意死锁问题。

如果两个线程分别持有对方需要的锁,就会产生死锁问题。

总之,synchronized是一个非常重要的同步机制,可以避免多线程环境下的数据竞争和数据不一致问题。

在写多线程程序时,合理使用synchronized可以使程序更加健壮和高效。

- 1 -。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Thread Synchronization/insidejvm/ed2/threadsynch.htmlOne of the strengths of the Java programming language is its support for multithreading at the language level. Much of this support centers on synchronization: coordinating activities and data access among multiple threads. The mechanism that Java uses to support synchronization is the monitor. This chapter describes monitors and shows how they are used by the Java virtual machine. It describes how one aspect of monitors, the locking and unlocking of data, is supported in the instruction set.MonitorsJava's monitor supports two kinds of thread synchronization: mutual exclusion and cooperation. Mutual exclusion, which is supported in the Java virtual machine via object locks, enables multiple threads to independently work on shared data without interfering with each other. Cooperation, which is supported in the Java virtual machine via the wait and notify methods of class Object, enables threads to work together towards a common goal.A monitor is like a building that contains one special room that can be occupied by only one thread at a time. The room usually contains some data. From the time a thread enters this room to the time it leaves, it has exclusive access to any data in the room. Entering the monitor building is called "entering the monitor." Entering the special room inside the building is called "acquiring the monitor." Occupying the room is called "owning the monitor," and leaving the room is called "releasing the monitor." Leaving the entire building is called "exiting the monitor."In addition to being associated with a bit of data, a monitor is associated with one or more bits of code, which in this book will be called monitor regions. A monitor region is code that needs to be executed as one indivisible operation with respect to a particular monitor. In other words, one thread must be able to execute a monitor region from beginning to end without another thread concurrently executing a monitor region of the same monitor. A monitor enforces this one-thread-at-a-time execution of its monitor regions. The only way a thread can enter a monitor is by arriving at the beginning of one of the monitor regions associated with that monitor. The only way a thread can move forward and execute the monitor region is by acquiring the monitor.When a thread arrives at the beginning of a monitor region, it is placed into an entry set for the associated monitor. The entry set is like the front hallway of the monitor building. If no other thread is waiting in the entry set and no other threadcurrently owns the monitor, the thread acquires the monitor and continues executing the monitor region. When the thread finishes executing the monitor region, it exits (and releases) the monitor.If a thread arrives at the beginning of a monitor region that is protected by a monitor already owned by another thread, the newly arrived thread must wait in the entry set. When the current owner exits the monitor, the newly arrived thread must compete with any other threads also waiting in the entry set. Only one thread will win the competition and acquire the monitor.The first kind of synchronization listed above, mutual exclusion, refers to the mutually exclusive execution of monitor regions by multiple threads. At any one time, only one thread can be executing a monitor region of a particular monitor. In general, mutual exclusion is important only when multiple threads are sharing data or some other resource. If two threads are not working with any common data or resource, they usually can't interfere with each other and needn't execute in a mutually exclusive way. On a Java virtual machine implementation that doesn't time slice, however, a higher priority thread that is never blocked will interfere with any lower priority threads, even if none of the threads share data. The higher priority thread will monopolize the CPU at the expense of the lower priority threads. Lower priority threads will never get any CPU time. In such a case, a monitor that protects no data may be used to orchestrate these threads to ensure all threads get some CPU time. Nevertheless, in most cases a monitor protects data that is accessed through the monitor region code. In cases where the data can be accessed only through the monitor regions, the monitor enforces mutually exclusive access to that data.The other kind of synchronization listed above as supported by monitors is cooperation. Whereas mutual exclusion helps keep threads from interfering with one another while sharing data, cooperation helps threads to work together towards some common goal.Cooperation is important when one thread needs some data to be in a particular state and another thread is responsible for getting the data into that state. For example, one thread, a "read thread," may be reading data from a buffer that another thread, a "write thread," is filling. The read thread needs the buffer to be in a "not empty" state before it can read any data out of the buffer. If the read thread discovers that the buffer is empty, it must wait. The write thread is responsible for filling the buffer with data. Once the write thread has done some more writing, the read thread can do some more reading.The form of monitor used by the Java virtual machine is called a "Wait and Notify" monitor. (It is also sometimes called a "Signal and Continue" monitor.) In this kind of monitor, a thread that currently owns the monitor can suspend itself inside the monitor by executing a wait command. When a thread executes a wait, it releases the monitor and enters a wait set. The thread will stay suspended inthe wait set until some time after another thread executes a notify commandinside the monitor. When a thread executes a notify, it continues to own the monitor until it releases the monitor of its own accord, either by executing a waitor by completing the monitor region. After the notifying thread has released the monitor, the waiting thread will be resurrected and will reacquire the monitor. The kind of monitor used in the Java virtual machine is sometimes called aSignal and Continue monitor because after a thread does a notify (the signal) itretains ownership of the monitor and continues executing the monitor region (the continue). At some later time, the notifying thread releases the monitor and awaiting thread is resurrected. Presumably, the waiting thread suspended itself because the data protected by the monitor wasn't in a state that would allow thethread to continue doing useful work. Also, the notifying thread presumablyexecuted the notify command after it had placed the data protected by the monitor into the state desired by the waiting thread. But because the notifyingthread continued, it may have altered the state after the notify such that the waiting thread still can't do useful work. Alternatively, a third thread may haveacquired the monitor after the notifying thread released it but before the waitingthread acquired it, and the third thread may have changed the state of the protected data. As a result, a notify must often be considered by waiting threads merely as a hint that the desired state may exist. Each time a waiting thread is resurrected, it may need to check the state again to determine whether it canmove forward and do useful work. If it finds the data still isn't in the desired state,the thread could execute another wait or give up and exit the monitor.As an example, consider once again the scenario described above that involves a buffer, a read thread, and a write thread. Assume the buffer is protected by a monitor. When a read thread enters the monitor that protects the buffer, it checks to see if the buffer is empty. If the buffer is not empty, the read thread reads (and removes) some data from the buffer. Satisfied, it exits the monitor. On the other hand, if the buffer is empty, the read thread executes a wait command. As soon as it executes the wait, the read thread is suspended and placed into themonitor's wait set. In the process, the read thread releases the monitor, which becomes available to other threads. At some later time, the write thread enters the monitor, writes some data into the buffer, executes a notify, and exits the monitor. When the write thread executes the notify, the read thread is marked for eventual resurrection. After the write thread has exited the monitor, the read thread is resurrected as the owner of the monitor. If there is any chance that some other thread has come along and consumed the data left by the write thread, the read thread must explicitly check to make sure the buffer is not empty. If there is no chance that any other thread has consumed the data, then the read thread can just assume the data exists. The read thread reads some data from the buffer and exits the monitor.A graphical depiction of the kind of monitor used by a Java virtual machine is shown in Figure 20-1. This figure shows the monitor as three rectangles. In thecenter, a large rectangle contains a single thread, the monitor's owner. On the left, a small rectangle contains the entry set. On the right, another small rectangle contains the wait set. Active threads are shown as dark gray circles. Suspended threads are shown as light gray circles.Figure 20-1 also shows several numbered doors that threads must "pass through" to interact with the monitor. When a thread arrives at the start of a monitor region, it enters the monitor via the leftmost door, door number one, and finds itself in the rectangle that houses the entry set. If no thread currently owns the monitor and no other threads are waiting in the entry set, the thread passes immediately through the next door, door number two, and becomes the owner of the monitor. As the monitor owner, the thread continues executing the monitor region. If, on the other hand, there is another thread currently claiming ownership of the monitor, the newly arrived thread must wait in the entry set, possibly along with other threads already waiting there. The newly arrived thread is blocked and therefore doesn't execute any further into the monitor region.Figure 20-1 shows three threads suspended in the entry set and four threads suspended in the wait set. These threads will remain where they are until the current owner of the monitor--the active thread--releases the monitor. The active thread can release the monitor in either of two ways: it can complete the monitor region it is executing or it can execute a wait command. If it completes the monitor region, it exits the monitor via the door at the bottom of the central rectangle, door number five. If it executes a wait command, it releases the monitor as it travels through door number three, the door to the wait set.If the former owner did not execute a notify before it released the monitor (and none of the waiting threads were previously notified and were waiting to be resurrected), then only the threads in the entry set will compete to acquire the monitor. If the former owner did execute a notify, then the entry set threads willhave to compete with one or more threads from the wait set. If a thread from the entry set wins the competition, it passes through door number two and becomes the new owner of the monitor. If a thread from the wait set wins the competition, it exits the wait set and reacquires the monitor as it passes through door number four. Note that doors three and four are the only ways a thread can enter or exit the wait set. A thread can only execute a wait command if it currently owns the monitor, and it can't leave the wait set without automatically becoming again the owner of the monitor.In the Java virtual machine, threads can optionally specify a timeout when they execute a wait command. If a thread does specify a timeout, and no other thread executes a notify before the timeout expires, the waiting thread in effect receives an automatic notify from the virtual machine. After the timeout expires, the waiting thread will be resurrected even if no other thread has executed an explicit notify.The Java virtual machine offers two kinds of notify commands: "notify" and "notify all." A notify command selects one thread arbitrarily from the wait set and marks it for eventual resurrection. A notify all command marks all threads currently in the wait set for eventual resurrection.To a great extent, the manner in which a Java virtual machine implementation selects the next thread from the wait or entry sets is a decision of individual implementation designers. For example, implementation designers can decide how to select:∙ a thread from the wait set given a notify command∙the order to resurrect threads from the wait set given a notify all command ∙the order to allow threads from the entry set to acquire the monitor∙how to choose between threads suspended in the wait set versus the entry set after a notify commandYou might think it would make sense to implement entry set and wait sets asfirst-in-first-out (FIFO) queues, so that the thread that waits the longest will be the first chosen to acquire the monitor. Alternatively, it might make sense to have ten FIFO queues, one for each priority a thread can have inside the Java virtual machine. The virtual machine could then choose the thread that has been waiting the longest in the highest priority queue that contains any waiting threads. Implementations may take approaches such as these, but you can't depend on it. Implementations are free to implement the entry and wait sets as last-in-first-out (LIFO) queues, to select lower priority threads before higher priority threads, or to do anything else that may not seem to make sense. In short, implementations are free to select threads in an arbitrary manner that defies analysis and yields surprising orderings.As a programmer, you must not rely on any particular selection algorithm or treatment of priorities, at least if you are trying to write a Java program that is platform independent. For example, because you don't know what order threads in the wait set will be chosen for resurrection by the notify command, you should use notify (as opposed to notify all) only when you are absolutely certain there will only be one thread suspended in the wait set. If there is a chance more than one thread will be suspended in the wait set at any one time, you should probably use notify all. Otherwise, on some Java virtual machine implementations a particular thread may be stuck in the wait set for a very long time. If a notify always selects the most recent arrival from the wait set and the wait set always contains multiple threads, some threads that have been waiting the longest may never be resurrected.Object LockingAs mentioned in earlier chapters, some of the Java virtual machine's runtime data areas are shared by all threads, others are private to individual threads. Because the heap and method area are shared by all threads, Java programs need to coordinate multi-threaded access to two kinds of data:∙instance variables, which are stored on the heap∙class variables, which are stored in the method area. Programs never need to coordinate access to local variables, which reside on Java stacks, because data on the Java stack is private to the thread to which the Java stack belongs.In the Java virtual machine, every object and class is logically associated with a monitor. For objects, the associated monitor protects the object's instance variables. For classes, the monitor protects the class's class variables. If an object has no instance variables, or a class has no class variables, the associated monitor protects no data.To implement the mutual exclusion capability of monitors, the Java virtual machine associates a lock (sometimes called a mutex) with each object and class. A lock is like a privilege that only one thread can "own" at any one time. Threads need not obtain a lock to access instance or class variables. If a thread does obtain a lock, however, no other thread can obtain a lock on the same data until the thread that owns the lock releases it. (To "lock an object" is to acquire the monitor associated with that object.)Class locks are actually implemented as object locks. As mentioned in earlier chapters, when the Java virtual machine loads a class file, it creates an instance of class ng.Class. When you lock a class, you are actually locking that class's Class object.A single thread is allowed to lock the same object multiple times. For each object, the Java virtual machine maintains a count of the number of times the object has been locked. An unlocked object has a count of zero. When a thread acquires the lock for the first time, the count is again incremented to one. Each time the thread acquires a lock on the same object, the count is again incremented. (Only the thread that already owns an object's lock is allowed to lock it again. As mentioned previously, no other thread can lock the object until the owning thread releases the lock.) Each time the thread releases the lock, the count is decremented. When the count reaches zero, the lock is released and made available to other threads.A thread in the Java virtual machine requests a lock when it arrives at the beginning of a monitor region. In Java, there are two kinds of monitor regions: synchronized statements and synchronized methods. (These are described in detail later in this chapter.) Each monitor region in a Java program is associated with an object reference. When a thread arrives at the first instruction in a monitor region, the thread must obtain a lock on the referenced object. The thread is not allowed to execute the code until it obtains the lock. Once it has obtained the lock, the thread enters the block of protected code. When the thread leaves the block, no matter how it leaves the block, it releases the lock on the associated object.Note that as a Java programmer, you never explicitly lock an object. Object locks are internal to the Java virtual machine. In your Java programs, you identify the monitor regions of your program by writing synchronized statements and methods. As the Java virtual machine runs your program, it automatically locks an object or class every time it encounters a monitor region.What is Thread.State in Java? What's it used for?Thread.State - This is a static nested class (Read more about nested classes in the article - Nested Classes & Inner Classes in Java >>) of the Thread class. This is one of the additions of Java 5 and this class actually inherits the abstract class Enum which is the common base class of all Java language enumeration types i.e., Thread.State is actually is actually an enumeration type.Thread.State enumeration contains the possible states of a Java thread in the underlying JVM. These states are different from the Operating System thread states. The possible values of the Thread.State are:-∙NEW - this state represents a new thread which is not yet started.∙RUNNABLE - this state represents a thread which is executing in the underlying JVM. Here executing in JVM doesn't mean that the thread isalways executing in the OS as well - it may wait for a resource from theOperating system like the processor while being in this state.∙BLOCKED - this state represents a thread which has been blocked and is waiting for a moniotor to enter/re-enter a synchronized block/method.Some one has said “A thread gets into this state after calling Object.waitmethod”, This is NOT correct. A thread enters BLOCKED state only when it is waiting to acquire the monitor(lock). That is, it is at the entry set inprevious graphic.Thread in this state in jstack looks likeThis is the state of thread that is waiting lock at entry set."3" prio=6 tid=0x00000000065f5800 nid=0x2264 waiting for monitor entry [0x0000000006fef000] ng.Thread.State: BLOCKED (on object monitor)at com.hk.MyThreads.process(MyThreads.java:25)- waiting to lock <0x00000000eb0eb980> (a com.hk.Token)at com.hk.MyThreads.run(MyThreads.java:17)This is the state of thread that entered waiting state early, later been waken by a NotiyAll() but unfortunately failed t o acquire the lock (many threads are waiting on this object but it’s not the lucky one), so enter the BLOCKED state, waiting for the lock."1" prio=6 tid=0x0000000006580800 nid=0x25d8 in Object.wait() [0x0000000006d9f000]ng.Thread.State: BLOCKE D (on object monitor)at ng.Object.wait(Native Method)- waiting on <0x00000000eb0ebda0> (a com.hk.Token)at ng.Object.wait(Object.java:485)at com.hk.MyThreads.process(MyThreads.java:31)- locked <0x00000000eb0ebda0> (a com.hk.Token)at com.hk.MyThreads.run(MyThreads.java:17)∙WAITING - this state represnts a thread in the waiting state and this wait is over only when some other thread performs some appropriate action. A thread can get into this state either by calling –o Object.wait (without timeout)o Thread.join (without timeout)o LockSupport.park methods.Thread in waiting set is in this state. Jstack shows them as"1" prio=6 tid=0x0000000006652800 nid=0x1cfc in Object.wait() [0x0000000006def000]ng.Thread.State: WAITING (on object monitor)at ng.Object.wait(Native Method)- waiting on <0x00000000eb0eb980> (a com.hk.Token)at ng.Object.wait(Object.java:485)at com.hk.MyThreads.process(MyThreads.java:30)- locked <0x00000000eb0eb980> (a com.hk.Token)at com.hk.MyThreads.run(MyThreads.java:17)∙TIMED_WAITING - this state represents a thread which is required to wait at max for a specified time limit. A thread can get into this state by callingeither of these methods:o Thread.sleep,o Object.wait (with timeout specified)o Thread.join (with timeout specified)o LockSupport.parkNanos,o LockSupport.parkUntilPay attention, as says above, calling thread.sleep and object.wait withtimeout will entry this state.(but for calling thread.sleep, the thread doesnot giveup the monitor/lock and object.wait will cause thread giveup lockon this object)"2" prio=6 tid=0x0000000006564800 nid=0x1e28 waiting on condition [0x0000000006e5f000]ng.Thread.State: TIMED_WAITING (sleeping)at ng.Thread.sleep(Native Method)at com.hk.MyThreads.process(MyThreads.java:27)- locked <0x00000000eb0eb980> (a com.hk.Token)at com.hk.MyThreads.run(MyThreads.java:17)"1" prio=6 tid=0x000000000654a000 nid=0x2228 in Object.wait() [0x0000000006d5f000]ng.Thread.State: TIMED_WAITING (on object monitor)at ng.Object.wait(Native Method)- waiting on <0x00000000eb0eb980> (a com.hk.Token)at com.hk.MyThreads.process(MyThreads.java:30)- locked <0x00000000eb0eb980> (a com.hk.Token)at com.hk.MyThreads.run(MyThreads.java:17)∙TERMINATED - this state reprents a thread which has completed its execution either by returning from the run() method after completing theexecution OR by throwing an exception which propagated from the run()method and hence caused the termination of the thread.Difference between BLOCKED state and WAITING / TIMED_WAITING states? When a thread calls Object.wait method, it releases all the acquired monitors (is this correct?it should only release current hold mointor) and is put into WAITING (or TIMED_WAITING if we call the timeout versions of the wait method) state. Now when the thread is notified either by notify() or by notifyAll() call on the same object then the waiting state of the thread ends and the thread starts attempting to regain all the monitors which it had acquired at the time of wait call. At onetime there may be several threads trying to regain (or maybe gain for the first time) their monitors. If more than one threads attempt to acquire the monitor of a particular object then only one thread (selected by the JVM scheduler) is granted the monitor and all other threads are put into BLOCKED state. Got the difference? Key points:1. For many threads waiting on an object, object.notifyAll() will wake all thesethreads but only one can acquire the lock. Others are transferred toBLOCKED state and waiting to acquire the lock in the same manner withother threads (no matter these threads is in first time to waiting the lock orbeen waken by the notifyAll()).2. object.notifyAll() will change state of all the threads that are waiting on thisobject (although only one can acquire the lock). That is, other call of notify() after notifyAll() if of no use.Difference between WAITING and TIMED_WAITING states?The difference is quite obvious between the two. A thread in a TIMED_WAITING state will wait at max for the specified timeout period whereas a thread in the WAITING state keeps waiting for an indefinite period of time. For example, if a thread has called Object.wait method to put itself into WA ITING state then it'll keep waiting until the thread is interrupted either by notify() method (OR by notifyAll() method) call on the same object by another thread. Similarly, if a thread has put itself into WAITING state by calling Thread.join method then it'll keep waiting until the specified thread terminates.We can easily figure out that a thread in a WAITING state will always be dependent on an action performed by some other thread whereas a thread in TIMED_WAITING is not completely dependent on an action performed by some other thread as in this case the wait ends automatically after the completion ofthe timeout period.1.线程suspend 和sleep的区别?2.继承Thread与实现Runnable?如果需要直接使用到Thread类的方法和属性,比如interrupt(),就用前者;否则可用Runnable。

相关文档
最新文档