aspose file tools*
The moose likes Threads and Synchronization and the fly likes yield() on synchronized code Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of EJB 3 in Action this week in the EJB and other Java EE Technologies forum!
JavaRanch » Java Forums » Java » Threads and Synchronization
Bookmark "yield() on synchronized code" Watch "yield() on synchronized code" New topic
Author

yield() on synchronized code

Mapraputa Is
Leverager of our synergies
Sheriff

Joined: Aug 26, 2000
Posts: 10065
yield() method on the current thread:
what happens if the current thread performs synchronized code: it will be forces to give the processor to other thread immediately (and what about lock?) or after synchronized code is finished?

Uncontrolled vocabularies
"I try my best to make *all* my posts nice, even when I feel upset" -- Philippe Maquet
Rahul Mahindrakar
Ranch Hand

Joined: Jul 28, 2000
Posts: 1836
I have broken up your questions into
1 yield() method does it give up the lock.
yield does give up the lock
2. what happens if the current thread performs synchronized code: it will be forces to give the processor to other thread immediately (and what about lock?)
The program below creates 3 threads in total. the first is the demo thead, then the t thread and then the sec thread.
the t thread is first started and starts running. This thread locks the class locking and the run method increments a static variable i.
Then the sec thread is started with a greater priority than the t thread. The t thread is immediately stoped by the processer and timeslice is given to the sec thread. If the t thread would not give up the lock then the sec thread would have had to wait, while t thread completes printing out upto Thread0-hi20. However since the t thread gives up the lock the sec thread does its work which is followed up by the t thread doing its work and printing out the remaining part.



the output of the program above is
output may be different in some computers
Hello World!
Thread-0 hi1
Second hi2
Second hi3
Second hi4
Second hi5
Second hi6
Second hi7
Second hi8
Second hi9
Second hi10
Second hi11
Second hi12
Second hi13
Second hi14
Second hi15
Second hi16
Second hi17
Second hi18
Second hi19
Second hi20
Second hi21
Thread-0 hi22
Thread-0 hi23
Thread-0 hi24
Thread-0 hi25
Thread-0 hi26
Thread-0 hi27
Thread-0 hi28
Thread-0 hi29
Thread-0 hi30
Thread-0 hi31
Thread-0 hi32
Thread-0 hi33
Thread-0 hi34
Thread-0 hi35
Thread-0 hi36
Thread-0 hi37
Thread-0 hi38
Thread-0 hi39
Thread-0 hi40
over

3.After synchronized code is finished what happens to the lock.
The lock is obviously released.
------------------
Regds.
Rahul P. Mahindrakar
[some extra code indentation added by Jim - hope you don't mind]
[This message has been edited by Jim Yingst (edited August 28, 2000).]
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
I disagree with Rahul's first answer - executing Thread.yield() does not give up any locks. Only wait() gives up a lock. yield() merely gives other threads a chance at processor time (with no guarantees) - if a thread needs a lock it can't get though, it still won't be able to run. Try the following:
<code><pre>
public class Test {

public static void main(String[] s) throws Exception {

Thread t1 = new Thread() {
public void run() {
synchronized (Test.class) {
System.out.println("t1 entered synchronized block");
for (int i = 0; i < 6; i++) {
System.out.println("t1 yielding");
Thread.yield();
System.out.println("t1 yielded");
try {
Thread.sleep(1000);
}
catch (InterruptedException e) {}
}
System.out.println("t1 leaving synchronized block");
}
}
};
t1.start();

Thread.sleep(500);

Thread t2 = new Thread() {
public void run() {
System.out.println("t2 attempting to enter synchronized block");
synchronized (Test.class) {
System.out.println("t2 entered synchronized block");
}
}
};

t2.setPriority(Thread.MAX_PRIORITY);
System.out.println("main() starting t2");
t2.start();
}
}
</pre></code>
The output is:
<code><pre>t1 entered synchronized block
t1 yielding
t1 yielded
main() starting t2
t2 attempting to enter synchronized block
t1 yielding
t1 yielded
t1 yielding
t1 yielded
t1 yielding
t1 yielded
t1 yielding
t1 yielded
t1 yielding
t1 yielded
t1 leaving synchronized block
t2 entered synchronized block
</pre></code>
Thread t1 gets a 500 millisecond head start, and grabs the lock on Thread.class. Thread t2 is set to maximum priority, but since t1 already has the lock, t2 can't get it until t1 releases it. The multiple yield() calls have no effect - t2 still can't get the lock.


"I'm not back." - Bill Harding, Twister
Mapraputa Is
Leverager of our synergies
Sheriff

Joined: Aug 26, 2000
Posts: 10065
I still confused.
1) I did not find any yield() in your code � does that mean that having a thread with high priority produces the same effect as yield()? Probably...
2) �If the t thread would not give up the lock then the sec thread would have had to wait, while t thread completes printing out upto Thread0-hi20.�
But in your run() method synchronized block is inside while loop, so sec thread can have lock after each printing, when t thread exits synchronized block � 15 good chances to get it.
I changed your run() method:

and now it prints:

Hello World!
Second hi1
Second hi2
Second hi3
Second hi4
Second hi5
Second hi6
Second hi7
Second hi8
Second hi9
Second hi10
Second hi11
Second hi12
Second hi13
Second hi14
Second hi15
over
Thread-0 hi16
Thread-0 hi17
Thread-0 hi18
Thread-0 hi19
Thread-0 hi20
Thread-0 hi21
Thread-0 hi22
Thread-0 hi23
Thread-0 hi24
Thread-0 hi25
Thread-0 hi26
Thread-0 hi27
Thread-0 hi28
Thread-0 hi29
Thread-0 hi30
My understanding: yield() stops the current thread only after synchronized block is finished. Am I wrong?
I have added UBB code tags to your text. Please use [ code] [ /code] without the spaces between [ and c ; [ and /c to put code.
[This message has been edited by Rahul Mahindrakar (edited August 28, 2000).]
Mapraputa Is
Leverager of our synergies
Sheriff

Joined: Aug 26, 2000
Posts: 10065
Sorry, while I typed my response, Jim already answered all my questions.
But there is another:
Bill Brogden �Java 2 Exam Cram�, Chapter 11, The Java AWT Components. p.225:
public void run() {
while (true)
doAnimationMoves();
animCanvas.repaint();
try {
Thread.yield();
} catch (InterruptedException ex) {
}
}
}
can anybody explain what is the purpose of try-catch statement in this code?
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
In my opinion, there is no purpose to the try/catch. Thread.yield() can't possibly throw an InterruptedException, since that is a checked exception (not a RuntimeException) and the declaration for yield() doesn't allow an InterruptedException.
Ah, I see that if you check the errata, Bill has already addressed this. Bill put a lot of good work into the errata - be sure to take advantage of it.
Rahul Mahindrakar
Ranch Hand

Joined: Jul 28, 2000
Posts: 1836
Mapraputa Is,
Yes you are right my run method is faulty with respect to the synchronized block.
Note when you are yielding the second thread (second) has a priority greater than that of the first thread Thread-0. Thus there is no way that the second thread would yield to the Thread-0 thread.
Lets state some rules about yield()
1) A thread yields only when there is another thread that has equal priority, is a runnable thread and the first thread does not hold any locks that is required by the second thread to execute its run method. (this is subject to the JVM being used these are just suggesstions that the JVM should run this way)
2) A thread does not yield to a lower priority thread.
3) A thread with a higher priority would be given timeslice whether yield is called or not.
so yield only works in the first case.
1. Making the priority of the two threads equal
I have tried this by removing the setPriority(10) statement and made the two threads have equal priority. But what has happened is that as Jim has rightfully pointed out yield() does not give up the lock as such the second thread is not able to lock on the Class locking. It thus goes back to waiting again giving control to the Thread-0 thread. The Thread-0 completes its work and then gives up the lock followed up by second thread completeing its work.
1. a Making priority of two threads equal and removing the synchronization.
I wanted to check out whether indeed the rule in 1 is correct so i checked out this. The result was that indeed calling yield by "if (i == 9) Thread.yield();" Thread-0 gives up control to second till it finished its work.
1. b Removing / not removing the synchronization and making the priority of second to 2.
Here i have checked up 2nd Rule "A thread does not yield to a lower priority thread.". The answer is that yielding by "if(i==9) Thread.yield();" Thread-0 does not give up control to second till it finishes its work.
However what i don't understand is that when a current thread performing synchronized code and is forced to give the processor to other thread the lock is released. Isn't a Object that was synchronized left in a corrupted state in such a scenario. If so how to take care of such a thing.
------------------
Regds.
Rahul P. Mahindrakar


[This message has been edited by Rahul Mahindrakar (edited August 28, 2000).]
Marcela Blei
Ranch Hand

Joined: Jun 28, 2000
Posts: 477
However what i don't understand is that when a current thread performing synchronized code and is forced to give the processor to other thread the lock is released. Isn't a Object that was synchronized left in a corrupted state in such a scenario. If so how to take care of such a thing.

Only with the wait() method a thread performing a synchronized block releases it�s lock, and that is a safe way, the object isn�t left in a corrupted state.
Mapraputa Is
Leverager of our synergies
Sheriff

Joined: Aug 26, 2000
Posts: 10065
yield() is static method and affects only the currently running thread. Does that mean that in systems with one processor yield() is always self-applied? I mean a thread cannot be interrupted by yield() produced by another thread?
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
Rahul- Marcela is right. There is no way another thread can force a thread to give up a lock; that can only be done by the thread that holds the lock, either using wait() or by exiting the section of code which synchronized on that lock. So if a lock must be given up to allow another thread to run, you have to write your code to make sure that can happen. But if that's not your intent, you don't have to worry about it happening accidentally.
Mapraputa- right, Thread.yield() always affects the thread it's called from, never another thread.
Rahul Mahindrakar
Ranch Hand

Joined: Jul 28, 2000
Posts: 1836
In my earlier post i had considered the following cases
1) A thread yields only when there is another thread that has equal priority, is a runnable thread and the first thread does not hold any locks that is required by the second thread to execute its run method. (this is subject to the JVM being used these are just suggesstions that the JVM should run this way)
2) A thread does not yield to a lower priority thread.
3) A thread with a higher priority would be given timeslice whether yield is called or not.
I had given needed examples to prove points 1 and 2.
What i was considering was case 3. What happens to a lock when a thread forcefullly takes up the timeslice from a thread that is holding a lock. I wrote a program as below

In the code above there is a lock associated with locking class. Initially this is held by "first" thread. The "second" thread is then started. If the lock is not given up by first only then second cannot get its work done and gives up control to first again even though it has higher priority. Does this happen??
invoking the program repetedly sometimes "first - 0" to "first -25" followed by "second -26" to "second-50" is being printed. like this
Case I output

This means that indeed first does not give up the lock.
However sometimes(execute the program few times) its also printing out this
case II output

If the lock is not released then the CASE II output should not be possible.
whats going on!!
By the way check out this article on How the Java virtual machine performs thread synchronization
------------------
Regds.
Rahul P. Mahindrakar


[This message has been edited by Rahul Mahindrakar (edited August 30, 2000).]
Marcela Blei
Ranch Hand

Joined: Jun 28, 2000
Posts: 477
Rahul: Look that the output should be: first all the "second"s or first all the "first"s but the release of the lock you are complaining would be:
second hi3
first hi4
second hi5
...etc.
which could not be possible in your above code.
The thing that changes from one execution to another is the order of the initialization of each thread

3) A thread with a higher priority would be given timeslice whether yield is called or not.

Timeslice is platform dependent, what the JVM uses to give up the processor to a thread of a higher priority is a premptive mechanism.

Anonymous
Ranch Hand

Joined: Nov 22, 2008
Posts: 18944
Regarding the most recent example above: It is possible (obviously) for the thread sec to begin running first occasionally.
When you call <code>start()</code> on a <code>Thread</code> object, it moves from the new to the ready state. From there, it will move between ready and running states largely at the discretion of the JVM thread that assigns actual processor time. If the thread encounters <code>synchronized</code> code, it then enters contention for the associated monitor's lock. In this case, don't forget there are more than two threads involved (<code>t</code>, <code>sec</code>, and the JVM's other threads, including the main program thread), and in a multithreaded program things don't always happen in a predictable order. If <code>t</code> is still in the state of contention for the lock of the <code>locking.class</code> object by the time <code>sec</code> is started, reaches the <code>synchronized</code> block, and enters contention for the lock, then there is an even chance that <code>sec</code> will get the lock. Priorities only affect the assignment of CPU time to threads in the ready state, not how locks are assigned to threads in contention.
I'm a bit disturbed by a couple of things in this, uh, thread...
One, there seems to be a bit of confusion about yielding. Threads can move from the running to the ready state in two ways - they can call <code>yield()</code> or they can have their CPU access forcefully removed by the JVM. We should differentiate between these cases, and only say "yield" when we mean "leaving the running state temporarily due to a call to <code>yield()</code>". In the other case, the thread doesn't "yield" the processor - it is forcefully removed from the running state by a JVM thread responsible for scheduling.
Second, there seems to be a lot of dependence on priorities to control the order of thread execution. JVM's are not really required to totally respect priorities, and some of them have different algorithms for handling relative priorities. (Didn't the Sun JVM change this algorithm between versions recently?) If you depend on priorities to control how your program runs, you'll likely find that it changes behavior between platforms, between JVM versions, and between single- and multiple-CPU machines.
Marcela Blei
Ranch Hand

Joined: Jun 28, 2000
Posts: 477
I agree with you in the first point only conceptually. Look that in the above code the two threads are trying to use the same synchronized code on the same locking class. So some part of the executing is predictable, you can say that first or second would run without an intersection of the other in the middle of it�s printlns. Take the following scenario: thread first starts executing, in a point of it�s loop the processor gives the control to thread second, so it began the run method and initialize the i variable, but inmediatelly it reaches the synchronized code, and the monitor has an owner, so it has to wait until the other thread finishes (the processor could give the control to the other thread a lot of times while the first is looping, but it allways try to take the synchronized code so it has to wait).
By the way of the preemptive mechanism, it isn�t platform dependent but it�s not an exact science, you are right that you can predict exactly it�s behavior but you know that a thread with high priority will take the processor over a thread with lower priority, if not: what are the thread priorities for?

[This message has been edited by Marcela Blei (edited August 31, 2000).]
Anonymous
Ranch Hand

Joined: Nov 22, 2008
Posts: 18944
Marcela;
About your example situation: priorities have no effect on a thread when its in the waiting state, only when its in ready/running.
About use of priorities in general: yes, they are useful, mostly in the case of unrelated threads which don't contend for the same locks. Given two threads in ready/running, most JVM's will favor the one with higher priority. Some will grant the CPU only to the higher priority thread, some will try to keep the lower priority thread from starving entirely, and some will lump threads into coarser priority categories and do round-robin scheduling within each category. I'm not saying that priorities aren't important; they're very useful in the case of unrelated threads (like a high-pri GUI vs. a low-pri background task). But if the two thread are related, then their relative execution should be handled with wait/notify on a common monitor object, so you can predict their behavior. I guess the main point I need to make here is that priorities are an entirely separate issue from synchronization, because priorities only affect threads in the ready and running states.
Marcela Blei
Ranch Hand

Joined: Jun 28, 2000
Posts: 477
About your example situation: priorities have no effect on a thread when its in the waiting state, only when its in ready/running.

??? When did I say that?
About the behaviour of thread priorities between different platforms I �m in doubt now, let�s find some material about that topic, I �ll do my work.

I guess the main point I need to make here is that priorities are an entirely separate issue from synchronization, because priorities only affect threads in the ready and running states.

Again??? There is no discussion about this point.
jply: I will be helpfull to know, if you don�t agree with the output I am describing about the code above, to explain me which could be the result and why?
Anonymous
Ranch Hand

Joined: Nov 22, 2008
Posts: 18944
Marcela;
I made those points because we were talking about the use of priorities, and your response (except for the last sentence) mentioned only synchronization, which has nothing to do with priorities.
If you're still thinking that priorities can be used to guarantee an execution order, then I propose a test: Write a short program with 3 threads. Each one is to print a string 10 times and exit. Let's say we want to see 5 lines from thread A, then 5 from B, then 5 from C, and then the cycle repeats. You implement it with priorities and no synchronization, and I'll implement it with synchronization and default priorities. Then we'll trade code and see if the other's still produces the same output. Sound OK?
P.S. By the way, I do agree with the output you described for your scenario. It's just that it has nothing to do with priorities.
[This message has been edited by jply (edited September 01, 2000).]
Marcela Blei
Ranch Hand

Joined: Jun 28, 2000
Posts: 477
jply: I know that synchronization and priorities are different things, by the way, about your last post I understand that we are talking about the same things, with different words. The only discussion point is that I said that priorities are not platform dependent so, the behaviour about them is similar in all OSs. I don�t want to mix that with synchronization but I want to find if what I�m saying is the truth. I think that we have to find some documentation to understand this point because it will be hard and no exactly to check by code examples.
Anonymous
Ranch Hand

Joined: Nov 22, 2008
Posts: 18944
Marcela;
Sorry for the confusion. About the use of priorities in various JVM's and in general, check out Lea (Concurrent Programming in Java), pp.14-15.
jply
P.S. Also the top of page 2 of this JavaWorld article. It's a little old, but mostly still relevant.
[This message has been edited by jply (edited September 04, 2000).]
Marcela Blei
Ranch Hand

Joined: Jun 28, 2000
Posts: 477
Thanks jply! I don�t have the book, I�m planning to buy it, but I�m in doubt between it and Java Thread Programming. But when I buy it I have to wait 30 days because the vendors have to import the book. I �ll read the article, thank you very much.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: yield() on synchronized code
 
Similar Threads
Thread
true false question for Thread
JTest and threads
Sleep and Yield.. Am i correct??
to yield() or not to yield()?