日期:2014-05-20  浏览次数:20798 次

请教:多线程中方法前加同步锁的问题
本人初学JAVA,请帮忙解读一下,这段落代码:

我以为会有死锁...可能我对synchronized加在方法前,到底是锁什么,还没搞清楚,请高手帮忙解读一下,谢谢!

package com.ocjp.testThread;

 public class Stubborn implements Runnable {
 static Thread t1;
 static int x = 5;
 
 public void run() {
 if(Thread.currentThread().getId() == t1.getId()) shove();
 else push();
 }
 
 static synchronized void push() { shove(); } //请问方法中的synchronized,是锁定对象么?
 
 static void shove() {
 synchronized(Stubborn.class) { //synchronized用于锁定整个Stubborn类;
 System.out.print(x-- +"   "); //输出是5 4 3 2 1 0;为什么有0?
 try { Thread.sleep(2000); } catch (Exception e) { ; }
 if(x > 0) push(); //这是递归么?退出递归的条件是x=0时,就不再调用了,应该输出打印5次,为什么打印出6个数?
 } }
 
 public static void main(String[] args) {
 t1 = new Thread(new Stubborn());
 t1.start();
 new Thread(new Stubborn()).start(); //如果这个线程先启动了,它调用push(),锁住方法所在的对象。。。此时t1线程,还有办法去调用push()方法么?push()的同步锁有什么用呢?
 } 
}
多线程 同步锁

------解决方案--------------------
你这是静态方法锁,调用此方法必须等其它线程用完才可以。
------解决方案--------------------
 static synchronized void push() { shove(); } //请问方法中的synchronized,是锁定对象么?
 静态方法加synchronized的关键字,调用它的话,得到的这个类Stubborn的锁。
------解决方案--------------------
static synchronized void push() { shove(); } //这里锁定的是这个方法 在没执行完之前其他线程是不能进入的
synchronized(Stubborn.class) { //synchronized用于锁定整个Stubborn类; 这里其实主要是要锁定X这个属性  当你使用的时候 其他线程不能使用  
 
不知道这样解释是不是清楚点
------解决方案--------------------
1 请问方法中的synchronized,是锁定对象么?
 public void synchronized f() {… } synchronizes on object itself (this), 非静态方法的synchronized锁定的是当前对象(this)
 public static void synchronized f() {… } synchronizes on Class instance of an object (object.getClass() or SomeClass.getClass),静态方法的synchronized锁定的是object.getClass()或者是SomeClass.getClass,是对象class的实例

2 synchronized用于锁定整个Stubborn类;输出是5 4 3 2 1 0;为什么有0?
其实有2中情况,t1线程优先进入run方法, 那么结果为 t1线程打印 5 4 3 2 1, 另外的线程(new Thread(newTestThread()).start())打印0, 还有一种情况 另外的线程优先进入, 那么就是另外的线程(new Thread(new TestThread()).start())打印 5 4 3 2 1, t1 打印0.

3 这是递归么?退出递归的条件是x=0时,就不再调用了,应该输出打印5次,为什么打印出6个数?
是递归,5个输出是一个线程的行为,而第6个数则是另外的线程的行为,而第6个数的打印总是要等到5个数组打印完成后,释放同步锁后,然后再打印。

4 如果这个线程先启动了,它调用push(),锁住方法所在的对象。。。此时t1线程,还有办法去调用push()方法么?push()的同步锁有什么用呢?
上面已经说过了,static的synchronized并不是锁住当前的对象,而是对象的class的实例。t1线程是没有办法调用push()方法的。push()的同步锁有什么用呢? 保证  x 变量能够被2个线程 串行 相加吧。