I am calling threadInfo.getBlockedCount() and getBlockedTime() just before the worker threads die.
I get a blocked count of 1, but a blocked time of 0.
Does this mean that the thread was blocked but it the blocked time was less than a millisecond?
If the above is true, is there another way to get accurate time for which a thread was blocked?
However, the blocked time of a thread (being blocked) only seems to return a non-zero result if the ThreadMXBean#setThreadContentionMonitoringEnabled(true) is called * before * starting the thread. Otherwise, it'd always return zero (or -1 if the contention monitoring is disabled). The code below demos this:
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
public class BlockedTimeMain {
public static void main(String[] _) throws InterruptedException {
ThreadMXBean mbean = ManagementFactory.getThreadMXBean();
final Object lock = new Object();
Thread t = new Thread("Foo") {
#Override public void run() {
// This will block forever
synchronized(lock) {
// Will never get here
System.out.println("Got the lock from " + Thread.currentThread());
}
}
};
synchronized(lock) {
t.start();
mbean.setThreadContentionMonitoringEnabled(true);
for (int i=0; i < 5; i++) {
ThreadInfo[] tis = mbean.getThreadInfo(new long[]{t.getId()}, true, true);
ThreadInfo ti = tis[0];
if (ti.getThreadId() != t.getId())
throw new AssertionError("Unexpected " + t.getId() + " vs " + tis[0].getThreadId());
System.out.println(t + " " + ti.getThreadState()
+ ": blockedTime=" + ti.getBlockedTime() + "/" + ti.getBlockedCount()
+ ", waitTime" + ti.getWaitedTime() + "/" + ti.getWaitedCount());
Thread.sleep(1000);
}
}
System.exit(0);
}
}
Sample Output:
Thread[Foo,5,main] BLOCKED: blockedTime=0/1, waitTime0/0
Thread[Foo,5,main] BLOCKED: blockedTime=0/1, waitTime0/0
Thread[Foo,5,main] BLOCKED: blockedTime=0/1, waitTime0/0
Thread[Foo,5,main] BLOCKED: blockedTime=0/1, waitTime0/0
Can test it out, with something like:
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
public class BlockedTimeMain {
public static void main(String[] _) throws InterruptedException {
ThreadMXBean mbean = ManagementFactory.getThreadMXBean();
mbean.setThreadContentionMonitoringEnabled(true);
final Object lock = new Object();
Thread t = new Thread("Foo") {
#Override public void run() {
// This will block forever
synchronized(lock) {
// Will never get here
System.out.println("Got the lock from " + Thread.currentThread());
}
}
};
synchronized(lock) {
t.start();
for (;;) {
ThreadInfo[] tis = mbean.getThreadInfo(new long[]{t.getId()}, true, true);
ThreadInfo ti = tis[0];
if (ti.getThreadId() != t.getId())
throw new AssertionError("Unexpected " + t.getId() + " vs " + tis[0].getThreadId());
System.out.println(t + " " + ti.getThreadState()
+ ": blockedTime=" + ti.getBlockedTime() + "/" + ti.getBlockedCount()
+ ", waitTime" + ti.getWaitedTime() + "/" + ti.getWaitedCount());
Thread.sleep(1000);
}
}
}
}
Sample Output:
Thread[Foo,5,main] BLOCKED: blockedTime=2/1, waitTime0/0
Thread[Foo,5,main] BLOCKED: blockedTime=1007/1, waitTime0/0
Thread[Foo,5,main] BLOCKED: blockedTime=2012/1, waitTime0/0
Thread[Foo,5,main] BLOCKED: blockedTime=3016/1, waitTime0/0
Thread[Foo,5,main] BLOCKED: blockedTime=4021/1, waitTime0/0
Thread[Foo,5,main] BLOCKED: blockedTime=5025/1, waitTime0/0
Thread[Foo,5,main] BLOCKED: blockedTime=6028/1, waitTime0/0
Thread[Foo,5,main] BLOCKED: blockedTime=7032/1, waitTime0/0
Thread[Foo,5,main] BLOCKED: blockedTime=8035/1, waitTime0/0
Yes it does mean that it was blocked for 0 milliseconds. i.e there was no blocking involved. The thread did not wait for the monitor lock to enter the synchronized block/method.
You are seeing this because you must have written a simple program with one or two threads, and there is no latency.
You will need to induce really heavy load on the threads to actually see positive values.
Apparently, that is what it means, and apparently there isn't a way to get the time to a greater precision. (The javadocs say that the blocked time may be measured and (presumably) accumulated with greater precision, but the ThreadInfo API doesn't expose this information, and there doesn't appear to be any other kosher way to get it.)
I say "apparently", because the javadoc actually describes the time values as "the approximate accumulated elapsed time". This leaves open the possibility that this could be a very rough approximation, possibly with the same granularity as the clock values returned by System.getCurrentTimeMillis(). Also, it doesn't say if accumulated times measured with a high precision timer would be rounded or truncated when converted to millisecond values; i.e. whether zero means "less than 1 millisecond" or "less than 0.5 milliseconds".
Related
I want to have a delay of 1 minute before the printFirst() method is called without affecting the main thread.
Code
I tried
// define delaying print-method using Timer
static void printFirst() {
new java.util.Timer().schedule(
new java.util.TimerTask() {
public void run() {
System.out.println(ts() + " First");
}
},60000
);
}
// main to run
System.out.println(ts() + " Zero");
printFirst();
printFirst();
printFirst();
System.out.println(ts() + " Second");
System.out.println(ts() + " Third");
System.out.println(ts() + " Fourth");
Actual Output
but the output was
Timestamp: 2023-01-05 17:40:43.664 Zero
Timestamp: 2023-01-05 17:40:43.666 Second
Timestamp: 2023-01-05 17:40:43.667 Third
Timestamp: 2023-01-05 17:40:43.667 Fourth
Timestamp: 2023-01-05 17:41:13.681 First
Timestamp: 2023-01-05 17:41:13.681 First
Timestamp: 2023-01-05 17:41:13.681 First
Expected
I was expecting an interval of 1 min between the 3 lines ending with "First".
Timestamp: 2023-01-05 17:40:43.664 Zero
Timestamp: 2023-01-05 17:40:43.666 Second
Timestamp: 2023-01-05 17:40:43.667 Third
Timestamp: 2023-01-05 17:40:43.667 Fourth
Timestamp: 2023-01-05 17:41:43.667 First
Timestamp: 2023-01-05 17:42:43.667 First
Timestamp: 2023-01-05 17:43:43.667 First
We can achieve the expected results using ExecutorService class with the newSingleThreadExecutor() method. See the code below.
static ExecutorService es = Executors.newSingleThreadExecutor();
static void printFirst() {
es.submit(() -> {
try {
TimeUnit.MILLISECONDS.sleep(60000);
System.out.println(ts() + " First");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
}
The main method is still the same.
System.out.println(ts() + " Zero");
printFirst();
printFirst();
printFirst();
System.out.println(ts() + " Second");
System.out.println(ts() + " Third");
System.out.println(ts() + " Fourth");
When run, the results are:
2023-01-06 00:05:45.72 Zero
2023-01-06 00:05:45.763 Second
2023-01-06 00:05:45.763 Third
2023-01-06 00:05:45.763 Fourth
2023-01-06 00:06:45.776 First
2023-01-06 00:07:45.782 First
2023-01-06 00:08:45.784 First
As an option you can set up your timer for periodic execution and limit the number of runs
static void printFirst(long delay, int numberOfIterations) {
new java.util.Timer().schedule(
new java.util.TimerTask() {
private int counter = 0;
public void run() {
System.out.println(ts() + " First");
if(++counter == numberOfIterations) {
this.cancel();
}
}
}, delay, delay
);
}
And then just run it with one command printFirst(60000, 3);
Issue
The delay in your Timer.schedule(TimerTask task, long initialDelay) is just for the initial delay, time between scheduled and start of task. See parameter in docs:
delay - delay in milliseconds before task is to be executed.
Solution
For your intent - as interval - you need the overloaded sister-method schedule(TimerTask task, long delay, long period) passing the 1 minute interval as third argument to parameter named period:
Schedules the specified task for repeated fixed-delay execution, beginning after the specified delay. Subsequent executions take place at approximately regular intervals separated by the specified period.
import java.util.Timer;
import java.util.TimerTask;
// define the task, here in a method on demand
public static TimerTask createPrintTask(String text) {
return new TimerTask() {
public void run() {
System.out.println(ts() + text); // not sure how ts() is defined
}
};
}
// define print-method using Timer with interval and zero delay
static void printScheduledWithInterval(String text, int intervalMillis) {
var initialDelayMillis = 0; // start immediately (first after 0 seconds)
new Timer().schedule(createPrintTask(text), initialDelayMillis, intervalMillis);
}
// MAIN
System.out.println(ts() + " Zero");
// use to start the task asynchronously (it will continue to print every interval until canceled)
printScheduledWithInterval(" First", 60_000); // 1 minute interval
System.out.println(ts() + " Second");
System.out.println(ts() + " Third");
System.out.println(ts() + " Fourth");
Note: In you code there was printFirst called 3 times. Presumably to have 3 different tasks started or to have 3 lines printed.
When does the scheduling of task end?
The printScheduledWithInterval here, rather means schedule a print-job to be executed repeatedly on a fixed-interval.
Since there are no requirements about number of printed lines or max-execution count, the timer will continuously start new tasks.
While calling function, you can set the number of seconds as a parameter
System.out.println(ts() + " Zero");
printFirst(60000);
printFirst(12000);
printFirst(18000);
System.out.println(ts() + " Second");
System.out.println(ts() + " Third");
System.out.println(ts() + " Fourth");
In your function,
static void printFirst(long time) {
new java.util.Timer().schedule(
new java.util.TimerTask() {
public void run() {
System.out.println(ts() + " First");
}
},time
);
}
I am study wait(long timeout) in java,and in the offcial document I found below description:
Some other thread invokes the notify method for this object and thread T happens to be arbitrarily chosen as the thread to be awakened.
Some other thread invokes the notifyAll method for this object.
Some other thread interrupts thread T.
The specified amount of real time has elapsed, more or less. If timeout is zero, however, then real time is not taken into consideration and the thread simply waits until notified.
The last item said The specified amount of real time has elapsed, more or less,so in my option if we invoke wait(time),when time elapsed,the thread should awake itself.
So I wrote below code for test.
public static void testTimedWait() {
Object lock = new Object();
DateTimeFormatter df = DateTimeFormatter.ofPattern("HH:mm:ss:SSS");
new Thread(() -> {
synchronized (lock) {
try {
System.out.println(LocalTime.now().format(df) + "\t" + Thread.currentThread().getName() + " start to run");
lock.wait(5_000);
System.out.println(LocalTime.now().format(df) + "\t" + Thread.currentThread().getName() + " finished running");
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}, "thread-1").start();
new Thread(() -> {
synchronized (lock) {
try {
System.out.println(LocalTime.now().format(df) + "\t" + Thread.currentThread().getName() + " start to run");
Thread.sleep(10_000);
//lock.notifyAll();
System.out.println(LocalTime.now().format(df) + "\t" + Thread.currentThread().getName() + " finished running");
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}, "thread-2").start();
}
In Thread-1 I invoke lock.wait(5_000) and in Thread-2 I invoke Thread.sleep(10_000),so once the code start to run,Thread-1 should awake after 5 seconds and Thread-2 should awake after 10 seconds theoretically.
When we run code above,the result listed like below:
Thread-1 doesn't awake after 5 seconds!
Could someone help to understand why thread not awake when the wait time has elasped,thanks in advance!
Update1:
Change code as below:
public static void testTimedWait() {
Object lock = new Object();
DateTimeFormatter df = DateTimeFormatter.ofPattern("HH:mm:ss:SSS");
new Thread(() -> {
synchronized (lock) {
try {
System.out.println(LocalTime.now().format(df) + "\t" + Thread.currentThread().getName() + " start to run");
lock.wait(20_000);
System.out.println(LocalTime.now().format(df) + "\t" + Thread.currentThread().getName() + " finished running");
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}, "thread-1").start();
new Thread(() -> {
synchronized (lock) {
try {
System.out.println(LocalTime.now().format(df) + "\t" + Thread.currentThread().getName() + " start to run");
Thread.sleep(10_000);
//lock.notifyAll();
System.out.println(LocalTime.now().format(df) + "\t" + Thread.currentThread().getName() + " finished running");
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}, "thread-2").start();
}
Above code make Thread-1 wait for 20 seconds and Thread-2 sleep for 10 seconds,Thread-1 will awake after the specific seconds.Now it works as expected.
Update2:
Remove Thread-2
public static void testTimedWait() {
Object lock = new Object();
DateTimeFormatter df = DateTimeFormatter.ofPattern("HH:mm:ss:SSS");
new Thread(() -> {
synchronized (lock) {
try {
System.out.println(LocalTime.now().format(df) + "\t" + Thread.currentThread().getName() + " start to run");
lock.wait(20_000);
System.out.println(LocalTime.now().format(df) + "\t" + Thread.currentThread().getName() + " finished running");
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}, "thread-1").start();
}
The test result is also working as expected.But I still do not know why Thread-1 not awake when it wait longer then Thread-2
Your threads are both synchronized on the same object. Therefore, you have to pay attention to the methods’s effect on synchronization:
Object.wait(…):
“This method causes the current thread (referred to here as T) to place itself in the wait set for this object and then to relinquish any and all synchronization claims on this object.”
…
“The thread T is then removed from the wait set for this object and re-enabled for thread scheduling. It competes in the usual manner with other threads for the right to synchronize on the object; once it has regained control of the object, all its synchronization claims on the object are restored to the status quo ante - that is, to the situation as of the time that the wait method was invoked.”
Thread.sleep(long): “The thread does not lose ownership of any monitors.”
So, when the first thread invokes wait, it releases the lock, which is the only way how the second thread could even enter the synchronized block. Then, the second thread calls sleep, which does not release the lock. Therefore, after the time has elapsed, the first thread can not proceed, as it can’t acquire the lock, the second thread is still holding.
Of course, if you extend the first thread’s waiting time, to wait longer than the second thread, the lock has been released in the meanwhile and the first thread can proceed immediately after the waiting time.
1. Set's parallelStream doesn't use enough thread.
Java8 parallelStream doesn't working exactly parallel.
In my computer, java8 set's parallelStream is not using enough thread when task's count is smaller than processor's count.
public class ParallelStreamSplitTest {
#Test
public void setStreamParallelTest() {
System.out.printf("Total processor count : %d \n", Runtime.getRuntime().availableProcessors());
long start = System.currentTimeMillis();
IntStream.range(1, 8).boxed().collect(Collectors.toCollection(HashSet::new)).parallelStream().forEach((index) -> {
System.out.println("Starting " + Thread.currentThread().getName() + ", index=" + index + ", " + new Date());
try {
Thread.sleep(1000);
} catch (Exception e) {
}
});
long end = System.currentTimeMillis();
System.out.println(Thread.currentThread().getName() + "'s elapsed time : " + (end - start));
}
#Test
public void intStreamParallelTest() {
System.out.printf("Total processor count : %d \n", Runtime.getRuntime().availableProcessors());
long start = System.currentTimeMillis();
IntStream.range(1, 8).parallel().forEach(index -> {
System.out.println("Starting " + Thread.currentThread().getName() + ", index=" + index + ", " + new Date());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
});
long end = System.currentTimeMillis();
System.out.println(Thread.currentThread().getName() + "'s elapsed time : " + (end - start));
}
}
In my code, setStreamParallelTest takes 4 seconds whereas intStreamParallelTest takes 1 second.
I expect that setStreamParallelTest also done in 1 seconds.
Is it bug?
2. Is it okay to use parallel stream to call another api in web application? If it is wrong, why?
My web application need to call another api server in parallel. So I use parallel stream to call api.
Sets.newHashSet(api1, api2, api3, api4).parallelStream().forEach(api -> callApiSync(api))
I think all requests bound for my server share a fork-join pool. so, It looks dangerous when one of api's response is slow.
Is it correct?
The contract for parallelStream says:
Returns a possibly parallel Stream with this collection as its source. It is allowable for this method to return a sequential stream.
If you want to invoke several tasks in parallel, use an ExecutorService.
I have read the explanation about blockingSubscribe() and subscribe() but neither I can write nor find an example to see the difference of these. It seems that both of these work the same way. Could someone provide an example of these 2, preferably in Java.
blockingSubscribe blocks the current thread and processes the incomnig events on there. You can see this by running some async source:
System.out.println("Before blockingSubscribe");
System.out.println("Before Thread: " + Thread.currentThread());
Observable.interval(1, TimeUnit.SECONDS)
.take(5)
.blockingSubscribe(t -> {
System.out.println("Thread: " + Thread.currentThread());
System.out.println("Value: " + t);
});
System.out.println("After blockingSubscribe");
System.out.println("After Thread: " + Thread.currentThread());
subscribe gives no such confinement and may run on arbitrary threads:
System.out.println("Before subscribe");
System.out.println("Before Thread: " + Thread.currentThread());
Observable.timer(1, TimeUnit.SECONDS, Schedulers.io())
.concatWith(Observable.timer(1, TimeUnit.SECONDS, Schedulers.single()))
.subscribe(t -> {
System.out.println("Thread: " + Thread.currentThread());
System.out.println("Value: " + t);
});
System.out.println("After subscribe");
System.out.println("After Thread: " + Thread.currentThread());
// RxJava uses daemon threads, without this, the app would quit immediately
Thread.sleep(3000);
System.out.println("Done");
I'm up for my exame presentation the day after tomorrow, so i need to get some straight before it which i hope you guys can help me with.
First i do know that there are 4 states of Threads (i.e Running, Ready, Blocked, Terminated), however i'm not quite sure how it works in Java. In my code i use the thread.sleep(3000) to do some waiting in the program, does this make the thread Blocked or Ready?
Also it have come to my attention that i might not have used the threads the right way, let me show you some code
public class BattleHandler implements Runnable {
private Player player;
private Monster enemyMonster;
private Dungeon dungeon;
private JTextArea log;
private GameScreen gScreen;
public void run() {
try {
runBattle();
}
catch(Exception e) { System.out.println(e);}
}
public BattleHandler(Player AttackingPlayer, JTextArea log, GameScreen gScreen) {
this.player = AttackingPlayer;
this.log = log;
this.gScreen = gScreen;
}
public void setDungeon(Dungeon dungeon) {
this.dungeon = dungeon;
}
public Dungeon getDungeon() {
return dungeon;
}
public Monster getEnemyMonster() {
return enemyMonster;
}
public void setMonster() {
// First check if dungeon have been init, if not we can't generate the mob
if(dungeon != null) {
enemyMonster = new Monster();
// Generate monster stats
enemyMonster.generateStats(dungeon);
}else {
System.out.println("Dungeon was not initialized");
}
}
public void runBattle() throws InterruptedException {
// Start battle, and run until a contester is dead.
while(player.getHealth() > 0 && enemyMonster.getHealth() > 0) {
int playerStrikeDmg = player.strike();
if(enemyMonster.blockDefend()) {
log.setText( log.getText() + "\n" + player.getName() +" tried to strike " + enemyMonster.getName()+ ", but " + enemyMonster.getName() + " Blocked.");
}else if(enemyMonster.dodgeDefend()) {
log.setText( log.getText() + "\n" + player.getName() +" tried to strike " + enemyMonster.getName()+ ", but " + enemyMonster.getName() + " Blocked.");
}else {
enemyMonster.defend(playerStrikeDmg);
log.setText( log.getText() + "\n" + player.getName() +" strikes " + enemyMonster.getName()+ " for: " + playerStrikeDmg + " left: "+ enemyMonster.getHealth());
}
if(enemyMonster.getHealth() < 1) break;
Thread.sleep(3000);
// Monster Turn
int monsterDmg = enemyMonster.strike();
if(player.blockDefend()) {
log.setText( log.getText() + "\n" + enemyMonster.getName() +" tried to strike " + player.getName()+ ", but " + player.getName()+ " Blocked.");
}else if(player.dodgeDefend()) {
log.setText( log.getText() + "\n" + enemyMonster.getName() +" tried to strike " + player.getName()+ ", but " + player.getName()+ " Dodged.");
}else {
player.defend(monsterDmg);
log.setText( log.getText() + "\n" + enemyMonster.getName() +" strikes " + player.getName()+ " for: " + monsterDmg + " left: "+ player.getHealth());
}
gScreen.updateBot();
Thread.sleep(3000);
}
When i coded this i thought it was cool, but i have seen some make a class just for controlling the Thread itself. I have just made the class who uses the Sleep runable(Which is not shown in the code, but its a big class).
Would be good to get this straight, so i can point i out before they ask me about it, you know take away there ammunition. :D
Hope you guys can help me :).
Thx
Threads have more than 4 states. Also, I recommend reading Lesson: Concurrency for more information regarding threads.
Note that if you're looking to execute a task at a set interval, I highly recommend using the Executors framework.
Blocked - it will not run at all until timeout. Ready is 'runnable now but there is no processor available to run it - will run as soon as a processor becomes available'.
As all the other guys state, there are more than those, here's a simple listing:
Running - Guess what, it's running
Waiting - It waits for another thread to complete its calculation (that's the wait() method in Java). Basically such a thread can also be run by the scheduler, like the "ready" state threads.
Ready - Means that the Thread is ready for execution, once the OS-Scheduler turns to this Thread, it will execute it
Blocked - Means that there is another operation, blocking this threads execution, such as IO.
Terminated - Guess what, it's done and will be removed by the OS-Scheduler.
For a complete listing, look at the famous Wikipedia ;)
http://en.wikipedia.org/wiki/Process_state