Reputation: 2234
I'm new to multiple-thread in java.I write some class to test functions of synchronized.I have some method using synchronized:
public class ShareUtil {
private static Queue<Integer> queue = new LinkedList<Integer>();
public static synchronized void do1(){
System.out.println("do1");
sleep();
}
public static synchronized void do2(){
System.out.println("do2");
sleep();
}
private static void sleep(){
try {
Thread.sleep(1000*50000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
You can see there are two method using synchronized,and I run two thread to use these two methods respectively.
class Run1 implements Runnable{
@Override
public void run() {
// TODO Auto-generated method stub
ShareUtil.do1();
}
}
class Run2 implements Runnable{
@Override
public void run() {
// TODO Auto-generated method stub
ShareUtil.do2();
}
}
public class DoMain {
public static void main(String[] args) {
ExecutorService pools = Executors.newCachedThreadPool();
for(int i=0;i<10;i++){
pools.execute(new Run1());
pools.execute(new Run2());
}
pools.shutdown();
}
}
But,it just print "do1" not print "do2".I want to know why?the key of "synchronized" using method to make the method only one thread use at the same time,but why lock the others method?
Upvotes: 0
Views: 112
Reputation: 33
I alter the code Thread.sleep(1000*50000);
to Thread.sleep(1000*2);
the output turns out to be irregular.
do2
do1
do1
do1
do1
do1
do1
do1
do1
do2
do2
do2
do2
do2
do2
do2
do2
do2
do1
We can see these thread is waiting for the lock of ShareUtil.class,and the lock is realesed after Thread.sleep
,one of the waiting Threads will grab the lock and turn to run.
Upvotes: 0
Reputation: 15755
The important key is synchronized
locks object, not method.
According to https://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html
Every object has an intrinsic lock associated with it. By convention, a thread that needs exclusive and consistent access to an object's fields has to acquire the object's intrinsic lock before accessing them, and then release the intrinsic lock when it's done with them. A thread is said to own the intrinsic lock between the time it has acquired the lock and released the lock. As long as a thread owns an intrinsic lock, no other thread can acquire the same lock. The other thread will block when it attempts to acquire the lock.
So, ShareUtil 's class intrinsic lock(your method is static
, so this is the intrinsic lock for the Class object associated with the class) is locked when Thread T1 is doing do1(), no other thread can acquire this lock unless T1 release it.
And the method sleep()
you call does not release this lock , while if you call wait()
it will , check Difference between wait() and sleep(). This is is the reason why when another Thread T2 try to access do2(), it must wait T1's do1() to complete(intrinsic lock is released).
Upvotes: 5
Reputation: 964
Run1() starts first acquires lock on the class ShareUtil, Followed by Run2() which is blocked until Run1() releases the lock. Once Run2() get the lock it will print do2(). Synchronized key guarantees only one thread access the method by acquiring lock on on class if the method is static or "object" if the method is instance.
Upvotes: 0
Reputation: 19700
Because when you synchronize a static
method, it acquires the lock on the Class
object. Once a thread has a lock on the Class
Object, none of the other threads can enter another static
method of the same class.
When you invoke sleep()
on a thread when it has the lock, None of the other threads can access the other static methods, because The thread does not lose ownership of the lock.
Hence sleep()
is causing only either of the thread to execute their methods. You can also get sometimes do2
printed but not do1
.
Upvotes: 1