Our teacher gave us the following code:
public static void main(String[]args) {
Thread a = new Thread(new T(2));
Thread b = new Thread(new T(5));
a.start();
b.start();
try {
a.join(); //Thread a now runs completely to the end, before the main-method gets back to a "runnable" state
b.join(); //Thread b runs to death before the main methods u
} catch (InterruptedException ie) {}
System.out.println("done"); //Result: Random Thread a and b outputs
//and in the end "done" from main
}
public class T extends Thread {
private int nr;
public T(int nr) {
this.nr = nr;
}
public void run() {
for (int i=0; i<10; i++) {
System.out.println("Hello " + nr + " " + i);
}
}
Thread a and b are the same and both write (in a for-loop) 10 prints to the console.
Thread a and b were finished, before the main method stopped and all results were random except the main method.
My question was, if it shouldn't also block the other threads(not just main), if you call join() on one thread. He said, that join() just freezes the main method. But for what reason should this be good? He also said, that this is totally random and managed by the scheduler, which doesn't make sense for this part in my opinion (the scheduler commands the thread-states, this is clear, but not after calling join(), at least not for the java application. Or am I false?). My point would be, that Thread a and b ran completely to the end, before the main-thread even called the join method. Javadoc tells me the same, if I understand it correct.
I hope someone of you can give me an answer. :)
The call to join() on an instance of Thread will not complete until the thread corresponding to that instance dies.
Corrollary 1: if that thread is already dead, join() returns immediately.
Corrollary 2: no threads except the current are affected by this call.
He also said, that this is totally random and managed by the scheduler
You probably didn't catch exactly what the teacher said here. Thread scheduling, which means making decisions when a thread will be given some CPU time to run, and how much of it, is done by the thread scheduler. It is definitely not "totally random" and for most practical considerations, all threads run all the time. Again, this has little to do with the behavior of the join method.
The point of join is not to give a single thread priority over all others. Rather, it's to express that one thread needs to wait for another thread to complete before that (first) thread can go on. It's not always the main thread calling join. It's a single constraint being placed on the scheduler: "Don't do A until you've done B". Of course, by using multiple joins, you can accomplish more complex dependencies.
I suspect that the point your teacher was trying to make is that you cannot assume anything other than the contract of join. I.e. the main thread will not continue until a has run to completion.
It is quite possible for a.join() to allow b to continue but it is also possible for it to completely block b until a is complete.
If you tested this code on a single-core machine it is actually quite likely that a.join() will exclude b but on a multi-core machine it may not.
Related
During the course of my program execution, a number of threads are started. The amount of threads varies depending on user defined settings, but they are all executing the same method with different variables.
In some situations, a clean up is required mid execution, part of this is stopping all the threads, I don't want them to stop immediately though, I just set a variable that they check for that terminates them. The problem is that it can be up to 1/2 second before the thread stops. However, I need to be sure that all threads have stopped before the clean up can continues. The cleanup is executed from another thread so technically I need this thread to wait for the other threads to finish.
I have thought of several ways of doing this, but they all seem to be overly complex. I was hoping there would be some method that can wait for a group of threads to complete. Does anything like this exist?
Just join them one by one:
for (Thread thread : threads) {
thread.join();
}
(You'll need to do something with InterruptedException, and you may well want to provide a time-out in case things go wrong, but that's the basic idea...)
If you are using java 1.5 or higher, you can try CyclicBarrier. You can pass the cleanup operation as its constructor parameter, and just call barrier.await() on all threads when there is a need for cleanup.
Have you seen the Executor classes in java.util.concurrent? You could run your threads through an ExecutorService. It gives you a single object you can use to cancel the threads or wait for them to complete.
Define a utility method (or methods) yourself:
public static waitFor(Collection<? extends Thread) c) throws InterruptedException {
for(Thread t : c) t.join();
}
Or you may have an array
public static waitFor(Thread[] ts) throws InterruptedException {
waitFor(Arrays.asList(ts));
}
Alternatively you could look at using a CyclicBarrier in the java.util.concurrent library to implement an arbitrary rendezvous point between multiple threads.
If you control the creation of the Threads (submission to an ExecutorService) then it appears you can use an ExecutorCompletionService
see ExecutorCompletionService? Why do need one if we have invokeAll? for various answers there.
If you don't control thread creation, here is an approach that allows you to join the threads "one by one as they finish" (and know which one finishes first, etc.), inspired by the ruby ThreadWait class.
Basically by newing up "watching threads" which alert when the other threads terminate, you can know when the "next" thread out of many terminates.
You'd use it something like this:
JoinThreads join = new JoinThreads(threads);
for(int i = 0; i < threads.size(); i++) {
Thread justJoined = join.joinNextThread();
System.out.println("Done with a thread, just joined=" + justJoined);
}
And the source:
public static class JoinThreads {
java.util.concurrent.LinkedBlockingQueue<Thread> doneThreads =
new LinkedBlockingQueue<Thread>();
public JoinThreads(List<Thread> threads) {
for(Thread t : threads) {
final Thread joinThis = t;
new Thread(new Runnable() {
#Override
public void run() {
try {
joinThis.join();
doneThreads.add(joinThis);
}
catch (InterruptedException e) {
// "should" never get here, since we control this thread and don't call interrupt on it
}
}
}).start();
}
}
Thread joinNextThread() throws InterruptedException {
return doneThreads.take();
}
}
The nice part of this is that it works with generic Java threads, without modification, any thread can be joined. The caveat is it requires some extra thread creation. Also this particular implementation "leaves threads behind" if you don't call joinNextThread() the full number of times, and doesn't have an "close" method, etc. Comment here if you'd like a more polished version created. You could also use this same type of pattern with "Futures" instead of Thread objects, etc.
When i assign a new value to variable it doesn't change after start(), however after i use join() it does. Why does this happen and in this case should int a be volatile or not?
class SampleThread extends Thread {
private static int a = 0;
#Override
public void run() {
a = 3;
}
public static void main(String[] args) throws InterruptedException {
Thread t2 = new Thread(new SampleThread());
t2.start();
System.out.println(a);
}
}
for seeing what is going on, try this:
...
#Override
public void run() {
System.out.println("start of Thread");
a = 3;
System.out.println("end of Thread");
}
...
only run method changed, rest of code unchanged
Yes, it needs volatile.
Every thread has an evil coin. The thread flips the coin anytime it reads or writes a field: Heads, and the thread uses its own local (to the thread) copy of it; if writing, that update simply does not reflect to all the other threads, who will still see the 'old' value, and if reading, same deal: Reads whatever it had, even though other threads updated it already. Even if they did so an hour ago. Tails, and it does refresh other threads' views of this thing, and won't use the local copy.
The coin is evil: it is not a fair coin. It will work every time today, and every time tomorrow, and every time during the test suite, and all throughout that week you have it live for the early adopting customers. And then juuust as that big client comes in and you're giving the demo? It flips to break your app every time. That kind of evil.
So, you must eliminate all coin flips, or at least ensure that the result of a coin flip does not affect your app whatsoever.
The way to do this, is to establish comes-before relationships. Between any 2 lines of java code as executed by a VM, there is a set of rules to determine if these 2 lines have such a relationship: That one is guaranteed to be run after the other. It's not about whether they did (timestamps of when they ran is completely irrelevant), it's whether the Java Memory Model decrees that such a relationship exists.
If yes, no coin is flipped: Anything the 'line that came before as per the JMM' did, is definitely visible to the line that came after. But if the JMM does not explicitly spell out that this relationship exists, the coin is flipped, and you lose.
One trivial 'comes before' relation ship is within a single thread: x = 5; System.out.println(x); trivially has such a relationship; they ran in the same thread, one came after the other. That's the freebie.
But between threads, oh dear. You need synchronized, volatile, or call code that does these things internally or has other mechanisms to ensure it (tip: There is lots of great stuff in the java.util.concurrent package, and as the name suggests, it's generally thread safe in very efficient ways. For example, an AtomicInteger is almost always far better than a volatile int, and can do far more, such as CAS operations, which volatile ints cannot do.
If you expect things in different threads to happen in a particular order -- in this case, that a = 2 is executed before `System.out.println(a)' -- then you have to write code to make that order happen.
In this trivial case, where no real work is being done, almost anything you can do makes the use of threads pointless. The main thread could 'join' the thread that's setting a to 2, but then all you've achieved is an expensive way to execute code that could be executed in a single thread.
main thread should wait that the other was executed
One solution is to use join()
class SampleThread extends Thread {
private static int a = 0;
#Override
public void run() {
a = 3;
}
public static void main(String[] args) throws InterruptedException {
Thread t2 = new Thread(new SampleThread());
t2.start();
// wait for completion of t2
t2.join()
System.out.println(a);
}
}
I have this code:
public class Nit extends Thread {
public void run() {
try {
synchronized(this) {
this.wait();
}
System.out.println("AAA");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Nit n = new Nit();
n.start();
synchronized(n) {
n.notify();
}
}
}
When I run it from cmd it never exits like it is an infinite loop. I don't understand why. Only thing i can think of is that Nit n is still waiting but I don't get why?
You are observing a race condition. You notify before the wait happens. Therefore the wait sits there and waits forever.
If you would invoke this code often enough, you might see it passing sometimes - when the new thread advanced faster then the main thread. One way to make the example work: try adding a call to Thread.sleep(1000) or so before calling notify(). Alternatively, even a println() call on the main thread (before the notify() might change timing enough).
Beyond that: such subtleties are the main reason why you actually avoid using the "low level" primitives such as as wait/notify. Instead, you use the powerful abstractions (like queues) that standard APIs have to offer.
The notify method tells the scheduler to pick a thread to notify, choosing from only those threads that are currently waiting on the same lock that notify was called on.
In this case the n thread doesn't start waiting until after the notification has already happened, so nothing ever wakes the thread up from waiting. You may have assumed that waiting threads will see notifications made before they started waiting, or that the JVM would have to give the n thread CPU time before the main thread proceeds past the call to start, but those assumptions aren't valid.
Introduce a condition flag as an instance member of Nit:
public class Nit extends Thread {
boolean notified = false;
and change Nit's run method to check it:
synchronized (this) {
while (!notified) {
wait();
}
}
Then add a line to the main method so that the main thread can set the flag:
synchronized (n) {
n.notified = true;
n.notify();
}
This way the notify can still happen before n starts waiting, but in that case n will check the flag, see it's true already, and skip waiting.
See Oracle's guarded blocks tutorial:
Note: Always invoke wait inside a loop that tests for the condition being waited for.
Also the API documentation (see Thread.join) discourages the practice of locking on thread objects.
I need a method that will run only once from the background no matter how many threads call it.
I found a partial solution using this code
my code:
public static void async(final int a){
Thread th = new Thread(new Runnable() {
#Override
public void run() {
meth(a);
}
});
th.start();
}
public static synchronized void meth(final int a){
try {
Thread.sleep(1000);
System.out.println(a);
} catch (InterruptedException ex) {
Logger.getLogger(Simple.class.getName()).log(Level.SEVERE, null, ex);
}
}
But when I test it like that:
System.out.println("start");
async(11);
async(12);
async(13);
async(14);
async(15);
async(16);
async(17);
async(18);
async(19);
System.out.println("end");
I got those results:
start
end
11
19
18
17
15
16
14
13
12
Is there anything wrong with my code?
Why the results are not in the same order as the call?
edited
after using Thread.join
public static Object obg = new Object();
public static void async(final int a){
Thread th = new Thread(new Runnable() {
#Override
public void run() {
meth(a);
}
});
th.start();
try {
th.join();
} catch (InterruptedException ex) {
Logger.getLogger(Simple.class.getName()).log(Level.SEVERE, null, ex);
}
}
public static synchronized void meth(final int a){
try {
Thread.sleep(1000);
System.out.println(a);
} catch (InterruptedException ex) {
Logger.getLogger(Simple.class.getName()).log(Level.SEVERE, null, ex);
}
}
i got this result which cancled the background work :
start
11
12
13
14
15
16
17
18
19
end
Thread.join didn't gave me the results I wish
edit for the third time to give example from other languages.
I tried the same code in c#
static void Main(string[] args)
{
Console.WriteLine("start");
async(11);
async(12);
async(13);
async(14);
async(15);
async(16);
async(17);
async(18);
Console.WriteLine("end");
}
static Object o = new Object();
public static void async(int a){
new Thread(() =>
{
lock (o)
{
Thread.Sleep(1000);
Console.WriteLine(a);
}
}).Start();
}
the results was in the same order
test results from swift language are the same as c#
so my question is : how to achieve those results in java
edit :
results of using the newly created thread in the join
code :
public static void main(String[] args) throws Exception {
System.out.println("start");
async(19,async(18,async(17,async(16,async(15,async(14,async(13,async(12,async(11,null)))))))));
System.out.println("end");
}
public static Object obg = new Object();
public static Thread async(final int a,final Thread other){
Thread th = new Thread(new Runnable() {
#Override
public void run() {
meth(a);
}
});
th.start();
try {
if(other!=null){
other.join();
}
} catch (InterruptedException ex) {
Logger.getLogger(Simple.class.getName()).log(Level.SEVERE, null, ex);
}
return th;
}
public static synchronized void meth(final int a){
try {
Thread.sleep(1000);
System.out.println(a);
} catch (InterruptedException ex) {
Logger.getLogger(Simple.class.getName()).log(Level.SEVERE, null, ex);
}
}
results :
start
11
12
13
14
15
16
17
18
end
19
background work was also canceled.
Your main thread starts nine others, giving each child thread a different a, and the first thing that all nine of those child threads do is sleep for one second.
The timing resolution in the Thread.sleep() call is undefined---It depends on the underlying operating system---and it's quite possible that all of the threads were elgible to wake up on the same tick of the system clock.
Java makes no guarantee that the threads will start running in the order that their Thread objects were start()ed, and it makes no guarantee that they will wake up in the order in which they went to sleep.
Any time you want things to happen in a certain order, the best way to make that happen is to do all of the things in a single thread.
I need this section to run sequentially...I don't want it to run twice or more at the same time...I still want it to run in the background.
OK., I get it now.
You probably want to use java.util.concurrent.Executors.newSingleThreadExecutor(). That function will return a thread pool with a single worker thread.
The worker thread will run tasks that you submit to the pool "in the background", and it will run them, one at a time, in the order that they were submitted.
static final ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
public static void async(final int a) {
singleThreadExecutor.submit(new Runnable() {
#Override
public void run() {
meth(a);
}
});
}
You appear to have two different questions here. You start by saying that you "need a method that will run only once from the background, no matter how many threads call it," which is one issue, and then you go on to say that the results from the different threads do not happen in the order that you want.
Question #1: Making the method run only once
You did not specify what exactly you mean by "run only once no matter how many threads call it." When it comes to multi-threaded programming, there are a few different common things that could be meant by that.Because of the example code you supplied, I will assume that you mean you want only one one at a time, but that you do want multiple calls to the method.
For this question, you are on the right track. If you have some data or action that you want to only be accessible to one thread at a time, the correct way to do that is to use a lock, also known as a mutex. In Java, this is done by creating an object to serve as a lock. The object can be of any class type - that part is not important. The important part is that all threads which need to have mutually exclusive access to some data or action all use the same instance of the locking object. A lock must be obtained on the object before the data or action is accessed, then it must be released after.
Now, with that theory part out of the way, the "synchronized" keyword you have applied to your method is more easily explained. When you apply synchronized to a Java method, what happens is that the "this" object, the one that "owns" the method (in your case, whichever object instance owns the call to meth(int)), is the object used as a lock. A lock is obtained on this before the body of the method is executed, and the lock is released after the body of the method is finished executing. This allows only one thread to access that code at a time.
Remember, though, that the different threads need to have the same instance of the lock object. If you have more than one object of whatever type you have there, then the different instances of the object can have their synchronized methods running concurrently with each other because they have separate locks.
This is probably more than sufficient to answer that part of this question, considering you were already using synchronized. For further reading, see the link I will supply at the bottom.
Question #2: Why are these threads happening out of order?
This question has a quick and easy answer: if you do not specifically do something to cause it to be otherwise, then no guarantee is ever made that the threads will ever happen in any specific order. It is as simple as that.
In your case, each thread sleeps for a second as the first thing it does, but that happens as part of that thread's action. Basically, all of your threads are all sleeping for a second at basically the same time, and then the second is up for all of them as basically the same time. And no guarantee is made about what order they will execute in.
If you had made it sleep in between instantiations of the new threads, then you probably would have caused the execution to be in the order you expected. That is, async(1); sleep; async(2); sleep; async(3); etc.. probably would have given you results more like what you seem to have been expecting, though that would sleep between every call to async and so would take a long time to finish everything. However, please note, this is not the way you should accomplish what you are looking for. Although you would probably get the output in the order you want if you sleep between calls to async, you are not guaranteed to get that order even then. For example, if your system is bogged down by other activities, it might throw off the timing such that one call to meth takes more than two seconds, so you have multiple threads waiting on the lock, and you once again get the results out of order.
Without direct intervention of some type, you are never guaranteed a thread execution order. If T1 and T2 are both executed or both waiting on a join or for whatever reason want to run, you never know which one will happen first. Usually there's no need to know.
If you need to force your threads to happen in a certain order - something which you generally want to try to avoid in order to maximize the liveness of your threads, but which sometimes is necessary - then try to take a look at some of the special Java concurrency objects which help get the timing that you might want. You can find some of them at the link I will provide below.
In the very specific case that you are supplying to us, if you just want a linear order (or even a tree-like order) where you have a set of threads {T1, T2, ..., Tn} you could use join, as you were starting to do (you were close again!), but make each thread join the one before it instead of all joining one thread. That is, have T2 join T1, T3 join T2, and so on. You can get linear execution this way, and you can also get a tree-like pattern: if you just care that T3 and T4 happen after T2 but you don't care which goes first between T3 and T4 then they can both join T2 - do this where you can to increase liveness.
If your end-goal is exactly like your question here where they are all executed linearly, you might be better off doing it in one single thread but having a list of actions that one thread needs to take, then that one thread can execute these things in order, each time it does all the actions and there's none left it then waits for more. This paragraph does not answer your question, but it's a suggestion about another way to do it, which may or may not be better depending on your use case.
And the link I mentioned...
Java Concurrency Trail
(edit: Sorry I botched the link the first time. Fixed.)
Check out that resource thoroughly. Notice the table of contents there to help you navigate around the sub-topics of Java concurrency. Some of the examples there might be difficult to grasp at first, but you seem to be going in the right direction. Keep at it.
I researched the concept of a thread and saw that it is to have code run in two processes at the same time. Heres my code though
public class Connor extends Thread{
public void run() {
for(int i=0; i< 10; i ++){
System.out.println("Hello " + i);
}
public static void main(String[] args){
Connor runner1 = new Connor();
Connor runner2 = new Connor();
runner1.start();
runner2.start();
}
}
And my output http://imgur.com/yAZqgal
It seems like the two threads do start off at the same time(separate processes, as indicated by the two leading 0s) but one executes (1-9) and then the other executes (1-9). Arent they suppose to interweave as well (1,1,2,2,...) bc the threads both print to the console. I researched and saw that start is the right method to use as it tells the thread class to execute the run method in another thread? Can anyone explain why im getting this output?
Say you have ten errands you need to do and your sister has ten errands she needs to do, and you only have one car. Do you bring the car back after each errand and switch drivers? Of course not. That would be absurdly inefficient. Each thread basically just needs the output stream. So it would be absurd to interleave them tightly.
Your code looks fine. I guess that your threads do not run in parallel just because they terminate to fast. Change the loop limit from 10 to 1000 and you will see the effect.
Starting thread itself is relatively heavy operation. You code starts the first thread and then the second one. The first thread once started terminates before the second thread got a chance to start executing its business logic.
In case of Multi-threading there is no guarantee that which thread is allocated for what time to run by the processor and in that case the result is unpredictable and will generate different output for each run.
If you are looking for desired output then you need synchronization block. using wait and notify you can achieve it easily.
Please have a look at below Lesson directly from Oracle official site:
Lesson: Concurrency to read more about concurrency.
Chapter 17. Threads and Locks to read more about thread, locks and synchronization.
Note: wait & notify must be called inside the synchronized block and can call on the same object on which it is synchronized.
Sample code: (read inline comments)
public class Connor extends Thread {
private static Connor runner1 = new Connor();
private static Connor runner2 = new Connor();
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("Hello " + i);
// wake up another thread to come out from wait state
if (runner1 == this) {
// wake up runner2
synchronized (runner2) {
runner2.notify();
}
} else {
// wake up runner1
synchronized (runner1) {
runner1.notify();
}
}
synchronized (this) {
try {
// say current thread to wait until notify by another thread
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
runner1.start();
runner2.start();
}
}
output:
Hello 0
Hello 0
Hello 1
Hello 1
Hello 2
Hello 2
Hello 3
Hello 3
Hello 4
Hello 4
Hello 5
Hello 5
Hello 6
Hello 6
Hello 7
Hello 7
Hello 8
Hello 8
Hello 9
Hello 9
Why my input is showing one thread executing after another thread, not at the same time?
The general explanation is that Thread scheduling is unpredictable. Interleaving may happen ... or it may not. That is fundamental to Java threading. (And indeed to threading in most other languages.)
If you need thread execution to interleave in an entirely predictable way, you need to implement some kind of hand-shake mechanism, where one thread waits for another one to do something, and do on. But that is complicated, and typically defeats the purpose of using threading.
FWIW: #Braj's answer shows how you might implement strict interleaving. However note that this effectively means that only one thread is going to execute at a time. In addition, the waiting / notifying is going to lead to a lot of work for the thread scheduler ... some that the application will run significantly slower than if you had just done the work on one thread.
In this particular example, there are two issues that combine to make any short term interleaving unlikely:
Creating a new native thread in Java is relatively expensive, because it typically entails requesting a memory block from the OS to house the thread stack. That in turn entails the OS "messing around" with page tables, zeroing a memory block and so on.
Native thread scheduling is implemented by the operating system, and it operates at a fairly coarse-grained level ... because that is the most efficient way to operate from the perspective of a typical application. (Switching thread "contexts" in a PC-class machine is relatively expensive operation, and the thread scheduler itself potentially has work to do.)
In your example, the chances are that the first thread can say "hello" ten times before the second thread is ready to be scheduled.