请教:多线程中方法前加同步锁的问题
本人初学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个线程 串行 相加吧。
[解决办法]
同步锁就是同一个方法同一时间里只能有一个线程在访问。那个可以理解为递归,另外肯定是打6次了,第一个线程进去打到 5,4,3,2,1后x--说明这是x是0了,第二个线程进来走shove()打印x为0后再--,最后x是-1不走了打印了6次。关于锁你自己找找,各种锁,自己多看看就知道了
[解决办法]
锁 说白了 就是使用权的问题。
假定有一个 厕所,里面就一个坑
10个人上厕所。难道一拥而上?岂不乱套了?!
这时候,就出来规矩,谁上厕所就吧门给锁了,其他人就等
等这人用完了,吧钥匙给下一个人 (钥匙给谁了? 这是JVM决定的!)
那么第一个去厕所的是谁呢? JVM决定的。
那么钥匙是什么呢? 钥匙就是 synchornized 关键字
每个人就是现场了。厕所....就是线程都想访问的那块数据了...
---
死锁就是
假定再加一个资源 手纸,要成功的上一次厕所,手纸不能缺
如果发生下面情况:
A 占了厕所没手纸, B 拿了手纸没占到厕所。
A要手纸,B要厕所,大家都上不成,就死了。
