What I need to do is use a FixedThreadPool of size 3 and then use it to print the ThreadName and then make it go to sleep for a random amount of time within a specified time interval and print that it is awake when it is done. I need to do it thread by thread but my output is coming with all the 3 threads together.
Desired output:
pool-1-thread-1 Going to sleep for random amount of time interval between 800 ms and 1000ms
pool-1-thread-1 done sleeping
pool-1-thread-2 Going to sleep for random amount of time interval between 800 ms and 1000ms
pool-1-thread-2 done sleeping
pool-1-thread-3 Going to sleep for random amount of time interval between 800 ms and 1000ms
pool-1-thread-3 done sleeping
I need to use FixedThreadPool only
import java.util.Random;
import java.util.concurrent.*;
class Sleep implements Runnable
{
public void run()
{
Random ran = new Random();
int randomnumber = ran.nextInt(1000-800+1)+800;
System.out.print(Thread.currentThread().getName()+" ");
System.out.println("Going to sleep for random amount of time interval between 800 ms and 1000ms");
try
{
Thread.sleep(randomnumber);
}
catch(Exception e)
{
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" done sleeping");
Thread.yield();
}
}
public class Ch6Ex3
{
public static void main(String[] args)
{
ExecutorService exe = Executors.newFixedThreadPool(3);
for(int i=0;i<3;i++)
{
exe.execute(new Sleep());
}
exe.shutdown();
}
}
Create thread pool with only 1 thread. If you use 3 threads then up to 3 runnable can be run concurrently and it's not what you want. So use:
ExecutorService exe = Executors.newFixedThreadPool(1);
Actually better option will be to use newSingleThreadExecutor because it explicitly shows that it runs only 1 runnable at any given time:
ExecutorService exe = Executors.newSingleThreadExecutor();
Internally both methods create ThreadPoolExecutor with 1 thread so there is no actual difference between them only in naming.
If you're creating the objects immediately after one another (within the same ms), they'll probably have the same seed in their Random instances - therefore they'll sleep for the same amount of time.
From javadoc:
Creates a new random number generator. Its seed is initialized to a value based on the current time:
public Random() { this(System.currentTimeMillis()); }
Two Random objects created within the same millisecond will have the same sequence of random numbers.
Besides that there's a problem in your code.
Thread.yield();
is redundant.
If you need that to execute one by one you don't need thread pool. You may just invoke Sleep#run from within your for loop creating different instances of Sleep class.
If you need that to work using FixedThreadPool and you wanna exactly 3 separate threads done your work you should use Locks. Like this: First thread is locking your Lock on entrance and unlocking on exit. Next threads will wait for Lock to relase and do the same stuff.
Read more here:
http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/locks/Lock.html
Related
Here is my code,
class Shared {
private static int index = 0;
public synchronized void printThread() {
try {
while(true) {
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName() + ": " + index++);
notifyAll();
// notify();
wait();
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class Example13 implements Runnable {
private Shared shared = new Shared();
#Override
public void run() {
shared.printThread();
}
}
public class tetest {
public static void main(String[] args) {
Example13 r = new Example13();
Thread t1 = new Thread(r, "Thread 1");
Thread t2 = new Thread(r, "Thread 2");
Thread t3 = new Thread(r, "Thread 3");
Thread t4 = new Thread(r, "Thread 4");
Thread t5 = new Thread(r, "Thread 5");
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
}
}
and the result is here
Thread 1: 0
Thread 5: 1
Thread 4: 2
Thread 3: 3
Thread 2: 4
Thread 3: 5
Thread 2: 6
Thread 3: 7
Thread 2: 8
Thread 3: 9
the question is, why only two of the threads are working? I'm so confused, I thought notify() is randomly wake up one of the waiting threads, but it's not.
is this starvation? then, why the starvation is caused? I tried notify() and notifyAll(), but got same results for both.
Can any one help my toasted brain?
This isn't 'starvation'. Your 5 threads are all doing nothing. They all want to 'wake up' - notify() will wake up an arbitrary one. It is neither unreliably random: The JMM does not ascribe an order to this, so one of them will wake up, you can't rely on it being random (do not use this to generate random numbers), nor can you rely on specific ordering behaviour.
It's not starvation (it's not: Oh no! Thread 2 and 3 are doing all the work and 4 and 5 are just hanging out doing nothing! That's bad - the system could be more efficient!) - because it doesn't matter which thread 'does the work'. A CPU core is a CPU core, it cares not which thread it ends up running.
Starvation is a different principle. Imagine instead of Thread.sleep (which means the threads aren't waiting for anything specific, other than some time to elapse), instead the threads want to print the result of some expensiv-ish math operation. If you just let 2 threads each say 'Hello!', then the impl of System.out says that it would be acceptable for the JVM to produce:
HelHellloo!!
So to prevent this, you use locks to create a 'talking stick' of sorts: A thread only gets to print if it has the talking stick. Each of 5 threads will all perform, in a loop, the following operation:
Do an expensive math operation.
Acquire the talking stick.
Print the result of the operation.
Release the talking stick.
Loop back to the top.
Now imagine that, despite the fact that the math operation is quite expensive, for whatever reason you have an excruciatingly slow terminal, and the 'print the result of the operation' job takes a really long time to finish.
Now you can run into starvation. Imagine this scenario:
Threads 1-5 all do their expensive math simultaneously.
Arbitrarily, thread 4 ends up nabbing the talking stick.
The other 4 threads soon too want the talking stick but they have to wait; t4 has it. They do nothing now. Twiddling their thumbs (they could be calculating, but they are not!)
after the excruciatingly long time, 4 is done and releases the stick. 1, 2, 3, and 5 dogpile on like its the All-Blacks and 2 so happens to win the scrum and crawls out of the pile with the stick. 1, 3, and 5 gnash their teeth and go back yet again to waiting for the stick, still not doing any work. Whilst 2 is busy spending the really long time printing results, 4 goes back to the top of the loop and calculates another result. It ends up doing this faster than 2 manages to print, so 4 ends up wanting the talking stick again before 2 is done.
2 is finally done and 1, 3, 4, and 5 all scrum into a pile again. 4 happens to get the stick - java makes absolutely no guarantees about fairness, any one of them can get it, there is also no guarantee of randomness or lack thereof. A JVM is not broken if 4 is destined to win this fight.
Repeat ad nauseam. 2 and 4 keep trading the stick back and forth. 1, 3, and 5 never get to talk.
The above is, as per the JMM, valid - a JVM is not broken if it behaves like this (it would be a tad weird). Any bugs filed about this behaviour would be denied: The lock isn't so-called "fair". Java has fair locks if you want them - in the java.util.concurrent package. Fair locks incur some slight extra bookkeeping cost, the assumption made by the synchronized and wait/notify system is that you don't want to pay this extra cost.
A better solution to the above scenario is possibly to make a 6th thread that JUST prints, with 5 threads JUST filling a buffer, at least then the 'print' part is left to a single thread and that might be faster. But mostly, the bottleneck in this getup is simply that printing - the code has zero benefit from being multicore (just having ONE thread do ONE math calculation, print it, do another, and so forth would be better. Or possibly 2 threads: Whilst printing, the other thread calculates a number, but there's no point in having more than one; even a single thread can calculate faster than results can be printed). Thus in some ways this is just what the situation honestly requires: This hypothetical scenario still prints as fast as it can. IF you need the printing to be 'fair' (and who says that? It's not intrinsic to the problem description that fairness is a requirement. Maybe all the various calculations are equally useful so it doesn't matter that one thread gets to print more than others; let's say its bitcoin miners, generating a random number and checking if that results in a hash with the requisite 7 zeroes at the end or whatever bitcoin is up to now - who cares that one thread gets more time than another? A 'fair' system is no more likely to successfully mine a block).
Thus, 'fairness' is something you need to explicitly determine you actually need. If you do, AND starvation is an issue, use a fair lock. new ReentrantLock(true) is all you need (that boolean parameter is the fair parameter - true means you want fairness).
This question already has answers here:
I get exception when using Thread.sleep(x) or wait()
(13 answers)
Closed 9 years ago.
I am currently writing a game and would like the app to wait a certain amount of time before proceeding. I have tried the sleep function and it does not do what I would like it to. I have a loop for ten and in that I would like one of the text boxes to have its value changed ten times with a couple of seconds gap between each one. So far I have this
for(int coolRan = 0; coolRan < 11; coolRan = coolRan + 1) {
Random generator = new Random();
int RanNumGen = generator.nextInt(50) + 1;
String RanNum = Integer.toString(RanNumGen);
higherTxt.setText(RanNum);
}
What I would like it to do after this is pause for a few seconds before performing the operation in the loop again so in Pseudocode this is what it looks like:
Loop For Ten
Generate Random Number With Maximum Value Of 50
Set A String To Equal The Random Number
Set A TextView To Equal The Random Number
Wait A Few Seconds
Perform Operation Again
The sleep method should work correctly if used in the following way.
Thread.sleep();
The parameter is the time in milliseconds.
For example:
Thread.sleep(5000);
//This pauses or "sleeps" for 5 seconds
Thread.sleep(long millis) makes the currently executing Thread sleep for long milliseconds (1/1000 seconds).
In Android, sleeping in the UI-thread is very, very bad practice and can for instance lead to a "Application Not Responsive" (ANR) error. To bypass this, you should run it off another thread. There are several ways to do this:
Calling View.postDelayed(Runnable action, long delayMillis) - this will delay it for you so you do not need to call sleep().
Making the task implement AsyncTask
Creating a new Thread (or Runnable) Java-style and then publishing it to the UI-thread with another Runnable (yeah.. not recommended) with Activity.runOnUiThread(Runnable)
Also note that your for-loop will run 11 times, from 0 up to 10 (both inclusive) - not 10 times.
I am slightly surprised by what I get if I compile and run the following (horrible non-synchronized) Java SE program.
public class ThreadRace {
// this is the main class.
public static void main(String[] args) {
TestRunnable tr=new TestRunnable(); // tr is a Runnable.
Thread one=new Thread(tr,"thread_one");
Thread two=new Thread(tr,"thread_two");
one.start();
two.start(); // starting two threads both with associated object tr.
}
}
class TestRunnable implements Runnable {
int counter=0; // Both threads can see this counter.
public void run() {
for(int x=0;x<1000;x++) {
counter++;
}
// We can't get here until we've added one to counter 1000 times.
// Can we??
System.out.println("This is thread "+
Thread.currentThread().getName()+" and the counter is "+counter);
}
}
If I run "java ThreadRace" at the command line, then here is my interpretation
of what happens. Two new threads are created and started. The threads have
the same Runnable object instance tr, and so they see the same tr.counter .
Both new threads add one to this counter 1000 times, and then print the value
of the counter.
If I run this lots and lots of times, then usually I get output of the form
This is thread thread_one and the counter is 1000
This is thread thread_two and the counter is 2000
and occasionally I get output of the form
This is thread thread_one and the counter is 1204
This is thread thread_two and the counter is 2000
Note that what happened in this latter case was that thread_one finished
adding one to the counter 1000 times, but thread_two had started adding
one already, before thread_one printed out the value of the counter.
In particular, this output is still comprehensible to me.
However, very occasionally I get something like
This is thread thread_one and the counter is 1723
This is thread thread_two and the counter is 1723
As far as I can see, this "cannot happen". The only way the System.out.println() line
can be reached in either thread, is if the thread has finished counting to 1000.
So I am not bothered if one of the threads reports the counter as being some
random number between 1000 and 2000, but I cannot see how both threads can
get as far as their System.out.println() line (implying both for loops have finished,
surely?) and counter not be 2000 by the time the second statement is printed.
Is what is happening that both threads somehow attempt to do counter++ at exactly
the same time, and one overwrites the other? That is, a thread can even be
interrupted even in the middle of executing a single statement?
The "++" operator is not atomic -- it doesn't happen in one uninterruptible cycle. Think of it like this:
1. Fetch the old value
2. Add one to it
3. Store the new value back
So imagine that you get this sequence:
Thread A: Step 1
Thread B: Step 1
Thread A: Step 2
Thread B: Step 2
Thread A: Step 3
Thread B: Step 3
Both threads think they've incremented the variable, but its value has only increased by one! The second "store back" operation effectively cancels out the result of the first.
Now, truth is, when you add in multiple levels of cache, far weirder things can actually happen; but this is an easy explanation to understand. You can fix these kinds of issues by synchronizing access to the variable: either the whole run() method, or the inside of the loop using a synchronized block. As Jon suggests, you could also use some of the fancier tools in java.util.concurrent.atomic.
It absolutely can happen. counter++ isn't an atomic operation. Consider it as:
int tmp = counter;
tmp++;
counter = tmp;
Now imagine two threads executing that code at the same about time:
Both read the counter
Both increment their local copy (0 to 1)
Both write 1 into counter
This sort of thing is precisely why java.util.concurrent.atomic exists. Change your code to:
class TestRunnable implements Runnable {
private final AtomicInteger counter = new AtomicInteger();
public void run() {
for(int x=0;x<1000;x++) {
counter.incrementAndGet();
}
System.out.println("This is thread "+
Thread.currentThread().getName()+" and the counter is " + counter.get());
}
}
That code is safe.
It seems that when I instantiate 12 Swing Worker threads, the first six starts to complete its task, it finishes AND then the last six starts and finishes. The behavior I'm looking for is all 12 threads start working at the same time & finish at the same time.
I have the following:
for (int i = 0; i < 12; i++ )
{
myTask m = new Mytask(i, START);
m.execute();
}
The myTask m will increment a progress bar from 0 - 100 in increments of 25. I'm getting outlandish behavior that the first six threads start incrementing, they finish at 100, then the last six threads start from 0 and increment, and finish.
Is there a limiting factor on the amount of Swing Worker threads one may have?
The behavior I'm looking for is all 12 threads start working at the same time & finish at the same time.
A CountDownLatch is designed for this very purpose. Here's a good example using a single SwingWorker and a number of subsidiary threads controlled by the latch.
SwingWorker class has a static ExecutorService field with MAX_WORKER_THREADS = 10. I'm not certain why you see 6 and not 10. But you cannot go over 10.
/**
* number of worker threads.
*/
private static final int MAX_WORKER_THREADS = 10;
...
executorService =
new ThreadPoolExecutor(1, MAX_WORKER_THREADS,
10L, TimeUnit.MINUTES,
new LinkedBlockingQueue<Runnable>(),
threadFactory);
Your question says:
The behavior I'm looking for is all 12
threads start working at the same time
& finish at the same time.
But you can't guarantee for all Swing workers threads starting concurrently and ending at same time.
Am I doing something really stupid here? I am trying to execute a method every minute or so, forever, or until I stop the program.
while(true) {
this.doSomethingPeriodically();
Calendar now = Calendar.getInstance();
int minutes = now.get(Calendar.MINUTE);
int resume = minutes + 1;
while (now.get(Calendar.MINUTE) < resume) {
// waiting for a minute
}
}
This code will never leave the loop. It's an endless loop, since the Calendar instance refered to by now won't change.
Also, what you try to do here is implement busy waiting which is a very bad idea (it uses CPU time doing nothing interesting).
The correct way to sleep is to use Thread.sleep().
the simplest way for execute tasks repeteadly in java is the java.util.TimerTask and java.util.Timer api.
A simple code is:
public class PrinterTimerTask extends java.util.TimerTask {
#Override
public void run() {
System.out.println( 'Current time is: ' + System.nanoTime() );
}
public static void main(String[] args) {
long delay = 0;
long period = 60000;
java.util.Timer timer = new java.util.Timer(threadName);
PrinterTimerTask task = new PrinterTimerTask();
timer = new Timer("SomeThreadNameForProfiler");
timer.schedule( task, delay, period );
}
}
Variables:
task - task to be scheduled.
delay - delay in milliseconds before task is to be executed.
period - time in milliseconds between successive task executions.
More info:
Timer and TimerTask javadoc:
http://java.sun.com/j2se/1.5.0/docs/api/java/util/Timer.html
http://java.sun.com/j2se/1.5.0/docs/api/java/util/TimerTask.html
Another example:
http://www.javapractices.com/topic/TopicAction.do?Id=54
[]'s,
And Past
Try using the Timer class instead. It's meant for this sort of thing:
http://www.javapractices.com/topic/TopicAction.do?Id=54
https://docs.oracle.com/javase/1.5.0/docs/api/java/util/Timer.html
Edit:
I just read that there's a newer replacement for Timer: ExecutorService. I've never used it, but it seems to have some advantages:
http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/ExecutorService.html
Java Timer vs ExecutorService?
Try using sleep instead, as it won't cause the processor to continue working on the thread:
Thread.sleep()
while(true) {
this.doSomethingPeriodically();
Thread.sleep(60000);
}
It would be better to use a Timer or at least use a sleep.
What you're trying to do here is called busy waiting. You are unnecessarily using huge amounts of CPU time (and you would even be using unnecessary memory if you fixed your bug and created a new Calendar instance in each loop).
What you actually want is the method Thread.sleep(), it is pretty well explained in a tutorial on sun.com.
It's better to use the sleep function: CurrentThread.sleep() and you specify the number of milliseconds that you want as a delay. It's better than busy waiting...