Please look at this code
public class Test extends Thread {
int i;
public Test(int i) {this.i = i;}
void simpleBlock() throws InterruptedException {
System.out.println(i + " this is an example of a thread blocking on itself - practicing concurrency 101, monitors, etc.");
synchronized(this) {wait();}
}
public void run() {
try {simpleBlock();} catch (InterruptedException e) {}
}
}
This is implemented by a Main class that creates and starts the threads
public class Main {
public static void main(String[] args) throws InterruptedException {
Test[] t = new Test[20];
for (int i=0; i<20; i++) {
t[i] = new Test(i);
t[i].start();
}
}
}
this prints the following output
0 this is an example of a thread blocking on itself - practicing concurrency 101, monitors, etc.
6 this is an example of a thread blocking on itself - practicing concurrency 101, monitors, etc.
4 this is an example of a thread blocking on itself - practicing concurrency 101, monitors, etc.
3 this is an example of a thread blocking on itself - practicing concurrency 101, monitors, etc.
5 this is an example of a thread blocking on itself - practicing concurrency 101, monitors, etc.
2 this is an example of a thread blocking on itself - practicing concurrency 101, monitors, etc.
1 this is an example of a thread blocking on itself - practicing concurrency 101, monitors, etc.
14 this is an example of a thread blocking on itself - practicing concurrency 101, monitors, etc.
7 this is an example of a thread blocking on itself - practicing concurrency 101, monitors, etc.
13 this is an example of a thread blocking on itself - practicing concurrency 101, monitors, etc.
12 this is an example of a thread blocking on itself - practicing concurrency 101, monitors, etc.
10 this is an example of a thread blocking on itself - practicing concurrency 101, monitors, etc.
11 this is an example of a thread blocking on itself - practicing concurrency 101, monitors, etc.
9 this is an example of a thread blocking on itself - practicing concurrency 101, monitors, etc.
8 this is an example of a thread blocking on itself - practicing concurrency 101, monitors, etc.
18 this is an example of a thread blocking on itself - practicing concurrency 101, monitors, etc.
19 this is an example of a thread blocking on itself - practicing concurrency 101, monitors, etc.
17 this is an example of a thread blocking on itself - practicing concurrency 101, monitors, etc.
16 this is an example of a thread blocking on itself - practicing concurrency 101, monitors, etc.
15 this is an example of a thread blocking on itself - practicing concurrency 101, monitors, etc.
Since SimpleBlock()
is not synchronized, I was expecting the prints to be chopped randomly. At least, that's what happened with another synchronization test I ran a while back, except that time I was using Semaphores (or lack thereof).
So why does each Thread print the full string in such a nice orderly fashion?
And this leads me to my next inquiry.
Let's say that simpleBlock
is fully synchronized, and the output is the same as above. So,
synchronized void simpleBlock() throws InterruptedException {
System.out.println(i + " this is an example of a thread blocking on itself - practicing concurrency 101, monitors, etc.");
wait();
}
As you may already know, this is equivalent to
void simpleBlock() throws InterruptedException {
synchronized(this) {
System.out.println(i + " this is an example of a thread blocking on itself - practicing concurrency 101, monitors, etc.");
this.wait();
}
}
Am I correct in assuming that since 20 threads are created in the Main class above, no two threads synchronize on a shared object since each thread is its own unique object, and because of this, synchronization schemes will effectively fail?
In other words, is it a bad idea to create many threads, each synchronizing on itself?
PrintStream.println
is synchronized
so your output is relatively orderly even if you have lots of threads.
From the source
/**
* Prints a String and then terminate the line. This method behaves as
* though it invokes <code>{@link #print(String)}</code> and then
* <code>{@link #println()}</code>.
*
* @param x The <code>String</code> to be printed.
*/
public void println(String x) {
synchronized (this) {
print(x);
newLine();
}
}