TIMED_WAITING Java thread state of

image

definition

A limit is waiting for another thread to perform an action thread in this state.

A thread that is waiting for another thread to perform an action for up to a specified waiting time is in this state.

More detailed definition or see javadoc (jdk8):

The state with the specified waiting time waiting threads located. A thread is in this state is because with a specified positive waiting time (parameter) called one of the following methods:

  • Thread.sleep
  • With time limit (timeout) of Object.wait
  • Thread.join with time limit (timeout) of
  • LockSupport.parkNanos
  • LockSupport.parkUntil

Corresponding to the English text as follows:

Thread state for a waiting thread with a specified waiting time. A thread is in the timed waiting state due to calling one of the following methods with a specified positive waiting time:

  • Thread.sleep
  • Object.wait with timeout
  • Thread.join with timeout
  • LockSupport.parkNanos
  • LockSupport.parkUntil

Not difficult to see the link between TIMED_WAITING and WAITING still very tight, the main difference in the time limit (timeout) on the parameters.

The other is different sleep on it.

timed_waiting scene

In fact, it comes in a chapter with no arguments wait () is equivalent to wait (0), and wait (0) 0 milliseconds, etc. It is not, on the contrary, it means a permanent wait, to forever unless notified.

Specific visible java source code and the corresponding javadoc, note: while there is also a special case, so-called "spurious wakeup" (false wake-up), we'll discuss below.

That is again the destiny of their activities entirely to someone else (informant), then this problem will exist?

Here, we go on to talk about the scene of a cabin in the chapter, such as unclear see  WAITING Java thread state of .

Imagine a situation, the crew increased the thread toilet paper, just as it is ready to execute notify, for some reason this thread was killed (also will be held by the lock release). In this case, the conditions have been met, but the waiting thread did not receive notice, still silly to wait.

In short, the presence of notification failure. At this time, if there is a thread effort prostitute, she was more thoughtful consideration, she is not calling wait (), but calls wait (1000), if put into the wait set likened to sleep waiting inside. So wait (1000) is equivalent to 1000 milliseconds comes with a countdown alarm clock, in other words, while waiting for her two notifications, and depending on whichever comes first:

  • If in 1000 milliseconds, she received a notice crew thread so as to awaken, alarm clock also will fail;
  • On the other hand, more than 1,000 milliseconds, not notified, the alarm sounded, this time were her alarm clock wake.

This is similar to double insurance. Here is a schematic diagram of a dynamic gif (empty cells represent conditions are not met, pink thread is responsible for increasing the paper's crew, passengers with representatives thread waiting alarm limit):

Thus, in the case of notice of failure, she still has a chance of self-awakened, and then complete the pee action.

Visible, a thread, with or without her table (alarm clock), the difference is still there. Go the other thread then waited and waited, until all wet but still below, which are not likely to notice. With the Uncle's words: It writings is quite uncomfortable.

The following code to simulate the above situation, this time, did not let the crew thread announcing action, but limit the waiting thread 2 or self-awakened:

@Test
public void testTimedWaitingState() throws Exception {

	class Toilet { // 厕所类
		int paperCount = 0; // 纸张

		public void pee() { // 尿尿方法
			try {
				Thread.sleep(21000);// 研究表明,动物无论大小尿尿时间都在21秒左右
			} catch (InterruptedException e) {
				Thread.currentThread().interrupt();
			}
		}
	}

	Toilet toilet = new Toilet();

	// 一直等待的线程1
	Thread passenger1 = new Thread(new Runnable() {
		public void run() {
			synchronized (toilet) {
				while (toilet.paperCount < 1) {
					try {
						toilet.wait(); // 条件不满足,等待
					} catch (InterruptedException e) {
						Thread.currentThread().interrupt();
					}
				}
				toilet.paperCount--; // 使用一张纸
				toilet.pee();
			}
		}
	});

	// 只等待1000毫秒的线程2
	Thread passenger2 = new Thread(new Runnable() {
		public void run() {
			synchronized (toilet) {
				while (toilet.paperCount < 1) {
					try {
						toilet.wait(1000); // 条件不满足,但只等待1000毫秒
					} catch (InterruptedException e) {
						Thread.currentThread().interrupt();
					}
				}
				toilet.paperCount--; // 使用一张纸
				toilet.pee();
			}
		}
	});

	// 乘务员线程
	Thread steward = new Thread(new Runnable() {
		public void run() {
			synchronized (toilet) {
				toilet.paperCount += 10;// 增加十张纸
				// 粗心的乘务员线程,没有通知到,(这里简单把代码注释掉来模拟)
				// toilet.notifyAll();// 通知所有在此对象上等待的线程
			}
		}
	});

	passenger1.start();
	passenger2.start();

	// 确保已经执行了 run 方法
	Thread.sleep(100);

	// 没有纸,两线程均进入等待状态,其中,线程2进入 TIMED_WAITING
	assertThat(passenger1.getState()).isEqualTo(Thread.State.WAITING);
	assertThat(passenger2.getState()).isEqualTo(Thread.State.TIMED_WAITING);

	// 此时的纸张数应为0
	assertThat(toilet.paperCount).isEqualTo(0);

	// 乘务员线程启动
	steward.start();

	// 确保已经增加纸张
	Thread.sleep(100);

	// 此时的纸张数应为10
	assertThat(toilet.paperCount).isEqualTo(10);

	// 确保线程2已经自我唤醒
	Thread.sleep(1000);

	// 如果纸张已经被消耗一张,说明线程2已经成功自我唤醒
	assertThat(toilet.paperCount).isEqualTo(9);

}

Wake false (spurious wakeup)

Although no parameters mentioned earlier wait () wait equivalent to (0), meaning that a permanent wait until notified. But in fact there is so-called "spurious wakeup", that is, the case of "false wake up", in particular visible javadoc Description Object.wait (long timeout) in:

A thread can also wake up without being notified, interrupted, or timing out, a so-called spurious wakeup. While this will rarely occur in practice, applications must guard against it by testing for the condition that should have caused the thread to be awakened, and continuing to wait if the condition is not satisfied.

In a thread can not be notified, interrupted or timed out wake, also known as "false wake-up", although this rarely happens in practice, the application should detect conditions leading to wake up a thread, and the condition is not satisfied in the case continue to wait, in order to prevent this.

In other words, wait you should always call (waits should always occur in loops) in a loop, javadoc given boilerplate code:

synchronized (obj) {
         while (<condition does not hold>)
             obj.wait(timeout);
         ... // Perform action appropriate to condition
     }

Simply speaking, if you want to avoid using the ways to determine the conditions, otherwise the thread once restored, will continue down, it does not detect the condition again. Because there may be a "false wake-up" does not mean that the condition is satisfied, wait for even this simple "Mouth" of the two threads / notify cases also need attention.

In addition, if the case more threads, such as "producers and consumers" problem, a producer and two consumers, not simply use more if judgment. Because it may use the notifyAll, two customers at the same time together, one of the first to grab the lock, a consumer, when waited for the other to grab the lock, may not meet the conditions, so we should continue to judge, we can not simply think was awakened condition is satisfied.

For more information on this topic, refer to:

  • Doug Lea 的 《Concurrent Programming in Java (Second Edition)》3.2.3 节。
  • Joshua Bloch 的 《Effective Java Programming Language Guide》,“Prefer concurrency utilities to  wait and  notify”章节。

Thread state of sleep

TIMED_WAITING into the state of sleep is another common method call scenarios, a separate thread can also call, do not have to have a cooperative relationship, of course, it can still be regarded as a special kind of wait / notify the situation.

This case is entirely on "bring your own alarm clock" to inform the.

Another: sleep (0) with the wait (0) is not the same, sleep does not wait indefinitely situation exists, sleep (0) is equivalent to almost no wait.

It should be noted, sleep method has no synchronization semantics. Normally, we would say, sleep method does not release the lock.

javadoc in the exact statement is:. The thread does not lose ownership of any monitors (thread does not lose ownership of any monitor)

The more exaggerated the argument is that it would hold when sleep lock hold, this argument can not say wrong, but is not very appropriate.

Make a less precise analogy, like you pointed to Tate's husband, said: "He will not come next month, aunt," Well, we can say that you do wrong? However, it is very strange.

To lock in terms of this issue, the exact argument is sleep is nothing to do with the lock.

JLS in to say that "It IS Important to note that neither Thread.sleep NOR Thread.yield have have the any
Synchronization semantics ." (Sleep and yield were not any synchronization semantics ), Another effect is that before or after they are calling without concern for consistency register cache and memory data (no flush or reload)

见《The Java Language Specification Java SE 7 Edition》17.3 Sleep and Yield

So, if the calling thread is to sleep with a lock, the lock also has a lock for the thread during sleep.

For example, calling sleep in sync block (requires special attention, perhaps you need is a method wait!)

Conversely, if there is no locking thread calls sleep (this is possible, this is different and wait, not really need to call in a synchronized block), then naturally it will not during sleep "cling to lock and hold."

Not lock you hold it Shane? The sleep-jun is entirely ignorant forced to face: "What is the lock lock I have not heard this stuff??!"

join scenario is similar to the wait with a timeout (timeout) principle, no longer expand the narrative here.

LockSupport.parkNanos and parkUnitl also referred the reader to the analysis.

And the differences and connections BLOCKED WAITING state

After finished BLOCKED, WAITING and TIMED_WAITING, we can take a look at them integrated, for example, blocking and waiting for the difference in the end there is what is the nature of it?

Obviously, it BLOCKED also be seen as a special, implicit wait / nofity mechanism. Wait condition is "locked or unlocked."

However, this is an uncertain wait, may wait (you can not obtain a lock), may not wait (can acquire the lock). After the fall of this blockage is no independent mechanism to exit.

One thing to note is that, BLOCKED status is associated with the Java synchronized mechanism language level, we know that the introduction of additional mechanisms (java.util.concurrent) after Java 5.0, in addition to this synchronized with internal locks, also You may be used outside the explicit lock.

Explicit lock has some better features, such as interrupts, settings can acquire the lock timeout, can have multiple conditions, though that from the surface, when explicitly lock can not be obtained, we say, the thread is "blocked "up, but not necessarily BLOCKED state.

When the lock is available, in which a thread is implicitly notify the system, and given the lock, so as to obtain the right to perform in sync blocks.

Obviously, waiting for the lock thread synchronization mechanisms and systems to form a collaborative relationship.

For comparison, WAITING state belongs to actively explicitly blocked applications, BLOCKED is a passive blocking, but whether it is a fundamental difference of view in the literal sense, there is no essential.

In the front we have said, these three states can be considered a traditional waiting state breakdown in the JVM level.

to sum up

Finally, with the traditional feed (line) divided by a final lift state comparison:

image

All the analysis about the state of Java threads on this point.

Guess you like

Origin blog.csdn.net/hellozhxy/article/details/94739510