Home > Archive > Java Help > June 2005 > How to run tasks with priority?
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
How to run tasks with priority?
|
|
| George George via JavaKB.com 2005-05-29, 8:58 am |
| Hello everyone,
I want to run tasks with priority, i.e. among several simultaneous running
tasks, the task with the higher priority will have more chances to occupy
CPU time. I have the following 2 issues dealing with the implementation of
such feature.
- To define each task as a thread or as a method? How to change the
priority of each task dynamically when they are running?
- The priority feature of Java thread does not meet my requirement, since I
can not define priority precisely. For example, I want to define that a
task with priority A will occupy CPU time 3 times than a task with priority
B.
I am wondering whether I can find similar open source projects or tutorials?
Thanks in advance,
George
--
Message posted via http://www.javakb.com
| |
| Boudewijn Dijkstra 2005-05-31, 4:03 pm |
| "George George via JavaKB.com" <forum@nospam.JavaKB.com> schreef in bericht
news:a4ce638f7c5543e4bb1f3c3d5e711194@Ja
vaKB.com...
> Hello everyone,
>
>
> I want to run tasks with priority, i.e. among several simultaneous running
> tasks, the task with the higher priority will have more chances to occupy
> CPU time. I have the following 2 issues dealing with the implementation of
> such feature.
>
> - To define each task as a thread or as a method?
It would generally be wise to allocate a thread for each task. How you define
the tasks, doesn't matter much.
> - How to change the
> priority of each task dynamically when they are running?
Thread#setPriority(int)
> - The priority feature of Java thread does not meet my requirement, since I
> can not define priority precisely. For example, I want to define that a
> task with priority A will occupy CPU time 3 times than a task with priority
> B.
You can accomplish this behaviour with the Thread#yield() method.
> I am wondering whether I can find similar open source projects or tutorials?
Similar to what?
| |
| George George via JavaKB.com 2005-06-01, 3:58 am |
| Thanks Boudewijn,
Your reply is very helpful! I found that if I use priority feature of Java
thread, then I can only have (MAX_PRIORITY - MIN_PRIORITY) different
priorities, which may limit my application. I am wondering whether there
are any alternate solutions which may have more different priorities.
> You can accomplish this behaviour with the Thread#yield
> () method.
How can I utilize utilize yield? Could you please give me a simple sample?
regards,
George
--
Message posted via http://www.javakb.com
| |
| Boudewijn Dijkstra 2005-06-01, 4:01 pm |
| "George George via JavaKB.com" <forum@JavaKB.com> schreef in bericht
news:00c78c327e394403907c1ce6b436fdd1@Ja
vaKB.com...
> Thanks Boudewijn,
>
> Your reply is very helpful! I found that if I use priority feature of Java
> thread, then I can only have (MAX_PRIORITY - MIN_PRIORITY) different
> priorities, which may limit my application. I am wondering whether there
> are any alternate solutions which may have more different priorities.
It sounds like you need to use synchronization, not priorities. With
synchronized{} blocks you can make threads wait for eachother at fixed points.
>
> How can I utilize utilize yield? Could you please give me a simple sample?
If two threads have the same priority and execute the same code, adding a
yield call to one of those, could make it run about twice as slow.
| |
| George George via JavaKB.com 2005-06-02, 4:01 am |
| Thanks Boudewijn,
> It sounds like you need to use synchronization, not
> priorities. With synchronized{} blocks you can make
> threads wait for eachother at fixed points.
It is a very good idea! I am not quite familar with the technology you
mentioned. Could you please provide me a simple sample?
> If two threads have the same priority and execute the
> same code, adding a yield call to one of those, could
> make it run about twice as slow.
I am wondering why should I use yield to make one thread run slower than
another one. I think thread with equal priority should have the same chance
to run. What is your purpose of using yield?
regards,
George
--
Message posted via JavaKB.com
http://www.javakb.com/Uwe/Forums.as...-setup/200506/1
| |
| Boudewijn Dijkstra 2005-06-02, 3:59 pm |
| "George George via JavaKB.com" <forum@JavaKB.com> schreef in bericht
news:b41eddf5e0834dcea8e19f19bfafde21@Ja
vaKB.com...
> Thanks Boudewijn,
>
>
>
> It is a very good idea! I am not quite familar with the technology you
> mentioned. Could you please provide me a simple sample?
Upon entry of a synchronized block, the thread waits to acquire a lock on the
specified object. Only one thread can hold the same lock at the same time.
Upon exit of the synchronized block, the lock is released. At this point,
other threads waiting to acquire the lock, may acquire the lock and then
continue execution. In the following (untested) example, Task1 will execute 3
times as slow as Task2.
class LockHolder {
private static final Object lock = new Object();
public static Object getLock() {
return lock;
}
}
class Task1 implements Runnable {
private static final Object lock = LockHolder.getLock();
public void run() {
while (true) {
synchronized (lock) {
stuff(1);
}
synchronized (lock) {
stuff(2);
}
synchronized (lock) {
stuff(3);
}
}
}
}
class Task2 implements Runnable {
private static final Object lock = LockHolder.getLock();
public void run() {
while (true) {
synchronized (lock) {
stuff(1);
stuff(2);
stuff(3);
}
}
}
}
>
> I am wondering why should I use yield to make one thread run slower than
> another one. I think thread with equal priority should have the same chance
> to run. What is your purpose of using yield?
To make the thread give away it's cycle to other threads with the same
priority. In other words, to reduce the execution time without reducing the
priority.
| |
| George George via JavaKB.com 2005-06-03, 3:58 am |
| Thanks Boudewijn,
Your sample is very helpful. But I think there is an issue in your sample,
which is that we must hardcode the number of sections that a code block
will be divided into. For example, in your sample, you hardcoded that Task1
is divided into 3 sections. I am wondering whether there are any approaches
which can flexibly define the number of sections in which a thread will be
divided into.
> To make the thread give away it's cycle to other
> threads with the same priority. In other words, to
> reduce the execution time without reducing the
> priority.
Are there any practical uses that we should give away it's cycle to other
threads with the same priority? Should we do it in this approach (yield)
manually or simply let JVM to do this.
Have a nice w end,
George
--
Message posted via JavaKB.com
http://www.javakb.com/Uwe/Forums.as...-setup/200506/1
| |
| Boudewijn Dijkstra 2005-06-03, 4:00 pm |
| "George George via JavaKB.com" <forum@JavaKB.com> schreef in bericht
news:1b0ed44698de4e4fb399a8187c1e13e0@Ja
vaKB.com...
> Thanks Boudewijn,
>
>
> Your sample is very helpful. But I think there is an issue in your sample,
> which is that we must hardcode the number of sections that a code block
> will be divided into. For example, in your sample, you hardcoded that Task1
> is divided into 3 sections. I am wondering whether there are any approaches
> which can flexibly define the number of sections in which a thread will be
> divided into.
You don't actually have to define your code into sections. It should even be
possible to change the number of synchronized accesses dynamically, by using a
loop inside your main loop:
for (int i = syncCount; i >= 0; ) {
synchronized (lock) {
i--;
}
}
> Are there any practical uses that we should give away it's cycle to other
> threads with the same priority?
Yes. You can use it in a lot of cases when you're using the sleep method, but
without the chance of actually idleing the CPU.
> Should we do it in this approach (yield)
> manually or simply let JVM to do this.
That is a decision that I cannot make for you. ;)
| |
| George George via JavaKB.com 2005-06-04, 3:57 pm |
| Thanks Boudewijn,
Boudewijn Dijkstra wrote:
>[quoted text clipped - 4 lines]
>
>You don't actually have to define your code into sections. It should even be
>possible to change the number of synchronized accesses dynamically, by using a
>loop inside your main loop:
>
>for (int i = syncCount; i >= 0; ) {
> synchronized (lock) {
> i--;
> }
>}
Do you mean that when the current thread leaves a synchronized block, it
will release the lock and then other threads will have chances to obtain
the lock?
>
>Yes. You can use it in a lot of cases when you're using the sleep method, but
>without the chance of actually idleing the CPU.
Do you mean using yield method will idle the CPU? If it is true, do you
know how to write a simple program to test that sleep method will not idle
CPU, and at the same time yield method will idle CPU?
Have a nice w end,
George
--
Message posted via JavaKB.com
http://www.javakb.com/Uwe/Forums.as...-setup/200506/1
| |
| Boudewijn Dijkstra 2005-06-04, 8:57 pm |
| "George George via JavaKB.com" <forum@JavaKB.com> schreef in bericht
news:66f2e92303ac409eade096696e2497a6@Ja
vaKB.com...
> Thanks Boudewijn,
>
>
> Boudewijn Dijkstra wrote:
>
> Do you mean that when the current thread leaves a synchronized block, it
> will release the lock and then other threads will have chances to obtain
> the lock?
Yes. And if you've read a primer about Java synchronization, you wouldn't
have to ask that question. ;)
>
> Do you mean using yield method will idle the CPU?
No. I said that with yield, there wasn't a chance of actually idling the CPU
(as long as there are other threads ready).
| |
| George George via JavaKB.com 2005-06-06, 3:59 am |
| Thanks Boudewijn,
Boudewijn Dijkstra wrote:
>[quoted text clipped - 3 lines]
>
>No. I said that with yield, there wasn't a chance of actually idling the CPU
>(as long as there are other threads ready).
Sorry that I do not express myself very clearly. I mean yield method will
make current thread idle on CPU (current thread will not occupy CPU time)
and it will give chances to other threads to run on CPU. Am I correct?
regards,
George
--
Message posted via JavaKB.com
http://www.javakb.com/Uwe/Forums.as...-setup/200506/1
| |
| blmblm@myrealbox.com 2005-06-06, 3:59 am |
| In article <42a08662$0$1335$5fc3050@dreader2.news.tiscali.nl>,
Boudewijn Dijkstra <usenet@bdijkstra.tmfweb.nl> wrote:
>"George George via JavaKB.com" <forum@JavaKB.com> schreef in bericht
> news:1b0ed44698de4e4fb399a8187c1e13e0@Ja
vaKB.com...
>
>You don't actually have to define your code into sections. It should even be
>possible to change the number of synchronized accesses dynamically, by using a
>loop inside your main loop:
>
>for (int i = syncCount; i >= 0; ) {
> synchronized (lock) {
> i--;
> }
>}
>
>
>Yes. You can use it in a lot of cases when you're using the sleep method, but
>without the chance of actually idleing the CPU.
>
>
>That is a decision that I cannot make for you. ;)
Doesn't it depend to some extent on whether the JVM implementation
tries to do timeslicing if there's more than one thread with
the same priority? As far as I know, some do and some don't.
Then again, it's probably best to write in a way that will work for
any standard-conforming implementation ....
(And -- clever idea. My initial reaction was that it wasn't going to
be possible to do what the OP wanted without a lot more knowledge of
exactly how long various parts of his code took and/or of how the
JVM schedules threads. But after thinking more -- yeah, I think
what you're proposing might actually work, though I wonder whether
there isn't some strange way a JVM could do scheduling that would
defeat your scheme.)
--
| B. L. Massingill
| ObDisclaimer: I don't speak for my employers; they return the favor.
| |
| Boudewijn Dijkstra 2005-06-06, 4:00 pm |
| "George George via JavaKB.com" <forum@JavaKB.com> schreef in bericht
news:ccbe4cc6a6a0411a813b5d5ab3fbd444@Ja
vaKB.com...
> Thanks Boudewijn,
>
>
> Boudewijn Dijkstra wrote:
>
> Sorry that I do not express myself very clearly. I mean yield method will
> make current thread idle on CPU (current thread will not occupy CPU time)
> and it will give chances to other threads to run on CPU. Am I correct?
That is correct. But yield will have no effect if the current thread is the
only 'ready' one with the same priority.
| |
| George George via JavaKB.com 2005-06-07, 4:03 pm |
| Thanks B. L. Massingill,
blmblm@myrealbox.com wrote:
>[quoted text clipped - 25 lines]
>
>Doesn't it depend to some extent on whether the JVM implementation
>tries to do timeslicing if there's more than one thread with
>the same priority? As far as I know, some do and some don't.
>Then again, it's probably best to write in a way that will work for
>any standard-conforming implementation ....
>
>(And -- clever idea. My initial reaction was that it wasn't going to
>be possible to do what the OP wanted without a lot more knowledge of
>exactly how long various parts of his code took and/or of how the
>JVM schedules threads. But after thinking more -- yeah, I think
>what you're proposing might actually work, though I wonder whether
>there isn't some strange way a JVM could do scheduling that would
>defeat your scheme.)
>
>| B. L. Massingill
>| ObDisclaimer: I don't speak for my employers; they return the favor.
Your reply is very helpful! From your reply, I think you are an expert in
this topic. I am very junior in the testing how JVM thread timeslice and
scheduling approach work. Could you provide some sample source codes to
test it?
Another issue is that, do you know where can I find resources (papers,
tutorials or open source projects) dealing with the internal operations of
JVM timeslice and scheduling approach?
regards,
George
--
Message posted via http://www.javakb.com
| |
| George George via JavaKB.com 2005-06-07, 4:03 pm |
| Thanks Boudewijn,
Boudewijn Dijkstra wrote:
>[quoted text clipped - 8 lines]
>
>That is correct. But yield will have no effect if the current thread is the
>only 'ready' one with the same priority.
>
Your reply is very helpful! I am wondering how can I write a simple program
to verify that the difference behavior of yield method and sleep method. Do
you have any good ideas?
regards,
George
--
Message posted via http://www.javakb.com
| |
| Boudewijn Dijkstra 2005-06-08, 4:01 pm |
| "George George via JavaKB.com" <forum@JavaKB.com> schreef in bericht
news:c5f97c90dab54524b5b6b298c37ed849@Ja
vaKB.com...
> Thanks Boudewijn,
>
>
> Boudewijn Dijkstra wrote:
>
> Your reply is very helpful! I am wondering how can I write a simple program
> to verify that the difference behavior of yield method and sleep method. Do
> you have any good ideas?
Make a thread that increments a variable as fast as it can. After every
increment it calls an abstract myWait() method that waits a number of
milliseconds. One implementation loops yield() until it reaches the wait
time. The other implementation simply calls sleep(long).
| |
| George George via JavaKB.com 2005-06-09, 8:58 am |
| Thanks Boudewijn,
Boudewijn Dijkstra wrote:
>[quoted text clipped - 10 lines]
>
>Make a thread that increments a variable as fast as it can. After every
>increment it calls an abstract myWait() method that waits a number of
>milliseconds. One implementation loops yield() until it reaches the wait
>time. The other implementation simply calls sleep(long).
>
I am wondering whether your testing method will work. Since if there is
only one thread in the system, yield will have no effect. But in your
description, there are only one thread. Our testing purpose is to verify
that yield method will idle CPU (if there are more than one threads running)
, while sleep will not idle CPU.
Maybe it is my mis-understanding of your description. It is highly
appreciated if you could write down your ideas into sample source codes.
regards,
George
--
Message posted via http://www.javakb.com
| |
| Boudewijn Dijkstra 2005-06-09, 8:58 pm |
| "George George via JavaKB.com" <forum@JavaKB.com> schreef in bericht
news:1017ecd7413146159805617139672d49@Ja
vaKB.com...
> Thanks Boudewijn,
>
>
> Boudewijn Dijkstra wrote:
>
> I am wondering whether your testing method will work. Since if there is
> only one thread in the system, yield will have no effect.
In this case "no effect" means that it will continue running, i.e. not
sleeping.
> But in your
> description, there are only one thread. Our testing purpose is to verify
> that yield method will idle CPU (if there are more than one threads running)
> , while sleep will not idle CPU.
>
> Maybe it is my mis-understanding of your description. It is highly
> appreciated if you could write down your ideas into sample source codes.
Agreed, but only because I became curious myself. ;)
Running the following test application should be accompanied by a CPU-usage
monitor program. First it will do a yield-test for 10 seconds, then it will
do a sleep-test for 10 seconds. Observe the difference in CPU usage. The
getFinalScore method doesn't really serve any purpose, besides maybe the
calculation of (TEST_TIME / WAIT_TIME).
public abstract class WaitTest
extends Thread
{
public static void main(String[] args)
{
WaitTest[] waitTest = new WaitTest[] {
new YieldWaitTest(),
new SleepWaitTest()
};
long TEST_TIME = 10000L;
try {
for (int i = 0; i < waitTest.length; i++)
{
WaitTest wt = waitTest[i];
System.out.print(wt.getTestName() + ": ");
wt.start();
Thread.sleep(TEST_TIME);
System.out.println(wt.getFinalScore());
}
} catch (InterruptedException ie) {
System.err.println("Interrupted");
System.exit(1);
}
}
static final int WAIT_TIME = 80;
boolean running = true;
int count = 0;
public void run()
{
int i = count;
while (running) {
try {
myWait();
} catch (InterruptedException ie) {
break;
}
i++;
}
count = i;
}
public int getFinalScore()
throws InterruptedException
{
running = false;
join();
return count;
}
// wait 80 ms
public abstract void myWait()
throws InterruptedException;
public abstract String getTestName();
}
class YieldWaitTest
extends WaitTest
{
public void myWait()
throws InterruptedException
{
long now = System.currentTimeMillis();
long target = now + WAIT_TIME;
while (true) {
Thread.yield();
if (target <= now)
break;
now = System.currentTimeMillis();
}
}
public String getTestName()
{
return "Yield";
}
}
class SleepWaitTest
extends WaitTest
{
public void myWait()
throws InterruptedException
{
Thread.sleep(WAIT_TIME);
}
public String getTestName()
{
return "Sleep";
}
}
| |
| George George via JavaKB.com 2005-06-10, 4:01 am |
| Thanks Boudewijn,
Boudewijn Dijkstra wrote:
>[quoted text clipped - 12 lines]
>
>In this case "no effect" means that it will continue running, i.e. not
>sleeping.
>
>[quoted text clipped - 3 lines]
>
>Agreed, but only because I became curious myself. ;)
>Running the following test application should be accompanied by a CPU-usage
>monitor program. First it will do a yield-test for 10 seconds, then it will
>do a sleep-test for 10 seconds. Observe the difference in CPU usage. The
>getFinalScore method doesn't really serve any purpose, besides maybe the
>calculation of (TEST_TIME / WAIT_TIME).
>
Your sample program is great! You mentioned that I should use CPU monitor
program. So I have tried and used performance monitor of task manager of
Windows XP (invoked from "My Computer") to monitor CPU usage. Am I correct?
I have found that when yield is running, the CPU usage is very high, and
when sleep is running, te CPU usage is very slow. Do you know why when
running yield, CPU usage is high? What is CPU busy doing at that time (in
my mind, I think CPU has nothing to do when running yield, just as when
running sleep)?
Another small issue is that, why you use join method in your getFinalScore
method? I have not seen its special functons yet.
Have a nice w end,
George
--
Message posted via JavaKB.com
http://www.javakb.com/Uwe/Forums.as...-setup/200506/1
| |
| blmblm@myrealbox.com 2005-06-11, 3:58 am |
| In article <99b185061b9c4e2e895b970e96c7c560@JavaKB.com>,
George George via JavaKB.com <forum@JavaKB.com> wrote:
>Thanks B. L. Massingill,
>
>
>blmblm@myrealbox.com wrote:
>
>Your reply is very helpful! From your reply, I think you are an expert in
>this topic. I am very junior in the testing how JVM thread timeslice and
>scheduling approach work. Could you provide some sample source codes to
>test it?
>
>Another issue is that, do you know where can I find resources (papers,
>tutorials or open source projects) dealing with the internal operations of
>JVM timeslice and scheduling approach?
>
Not expert by any means, just dimly aware that different
implementations do take different approaches to scheduling when
there's more than one thread with the same priority. Below is a
quickly-hacked-together little program that should give some clues
about what a particular implementation does. If the implementation
is doing timeslicing at all, then for a "large enough" value of
N you should observe that the messages produced by the first loop
("no yield") in both threads are interspersed. If it's not doing
timeslicing, then the first message from thread "pong" won't show up
until after thread "ping" has finished that first loop.
As for getting into the details of how particular implementations do
scheduling -- I'm not sure I'd advise this unless you need very
precise control over the scheduling of your threads and/or don't
care about portability. The standard advice is to write your code
to work with any implementation that meets the published specs,
which are probably available at Sun's Web site, somewhere. Sorry
I don't have time to track down more details.
/* No claims are made about the beauty or generality of this code,
only that it compiles and executes for me and I think produces
some useful information.
*/
public class PingPong {
public static void main(String[] args) {
if (args.length < 1) {
System.err.println("usage: PingPong count");
System.exit(1);
}
int count = Integer.parseInt(args[0]);
new Thread(new CodeForThread(count, "ping")).start();
new Thread(new CodeForThread(count, "pong")).start();
}
private static class CodeForThread implements Runnable {
private int count;
private String name;
public CodeForThread(int count, String name) {
this.count = count;
this.name = name;
}
public void run() {
System.out.println("thread " + name + " will now print "
+ count + " messages without using Thread.yield");
for (int i = 0; i < count; ++i) {
System.out.println("in thread " + name + " (no yield)");
}
System.out.println("thread " + name + " will now print "
+ count + " messages using Thread.yield");
for (int i = 0; i < count; ++i) {
System.out.println("in thread " + name + " (yield)");
Thread.yield();
}
}
}
}
--
| B. L. Massingill
| ObDisclaimer: I don't speak for my employers; they return the favor.
|
|
|
|
|