当前位置: 技术问答>java相关
关于线程
来源: 互联网 发布时间:2015-09-13
本文导语: 1。一个线程调用notify(),是否这个线程马上失去了锁? 2。如果一个线程开始在wait,那么当这个线程被notify唤醒后,如果调用notify的线程还继续拥有锁,那么被唤醒的线程怎么办呢? | 不一定 先...
1。一个线程调用notify(),是否这个线程马上失去了锁?
2。如果一个线程开始在wait,那么当这个线程被notify唤醒后,如果调用notify的线程还继续拥有锁,那么被唤醒的线程怎么办呢?
2。如果一个线程开始在wait,那么当这个线程被notify唤醒后,如果调用notify的线程还继续拥有锁,那么被唤醒的线程怎么办呢?
|
不一定
先给你解释一下,每个对象都有一个锁计数器,他保存着当前锁的owner有几个synchronized方法被调用。锁的owner每调用一个新的synchronized方法,计数器++,每次synchronized方法退出时,计数器--;计数器为0时,解锁。
这样,如果一个线程调用了synchronized方法而得锁,计数器为1,这个方法因为某些条件不满足,不能继续,用wait挂起自己,然后,其他线程有机会调用了另一个synchronized方法来满足这个条件,并且在退出前调用了notify或者notifyAll来通知刚才那个被挂起的线程,使之能继续运行。这是一般情况,但是如果这种情况,刚才那个线程在synchronized方法A中没有wait来挂起自己,而是调用了他拥有的对象的另一个方法B,满足了条件,注意,这时他拥有的对象的锁计数器为2,她调用notify,这个synchronized方法B退出之后,锁计数器变为1,所以,这个线程还有钥匙,仍然不放弃此对象,只当A也退出时,锁计数器才变为0,这个线程才松手,下面是我写的两个例子,来说明这个问题,例子一:假设Daniel是个很有钱的人,总往垃圾箱里扔东西,而Kate和Jack很穷,总去垃圾箱捡Daniel扔的东西,直到30为止,可能是垃圾箱被城管挪走了,程序结束。这是正常情况。
public class WaitNotifyTest
{
public static void main(String[] args)
{
Dustbin db = new Dustbin();
PeopleThread people1 = new PeopleThread(db, "Daniel");
PeopleThread people2 = new PeopleThread(db, "Jack");
PeopleThread people3 = new PeopleThread(db, "Kate");
people1.start();
people2.start();
people3.start();
}
}
class Dustbin
{
private int tonnage = 0;
private int operation = 0;
public boolean end()
{
return operation>30;
}
public synchronized void get(String operator)
{
int op = operation++;
System.out.println(operator + " Operation " + op + " is a get call, current tonnage is " + tonnage);
try
{
while(tonnage30;
}
public synchronized void get(String operator)
{
int op = operation++;
System.out.println(operator + " Operation " + op + " is a GET call, current tonnage is " + tonnage);
try
{
while(tonnage0.5)
dustbin.put(name);
else
dustbin.get(name);
}
}
catch (Exception e)
{System.out.println(e);}
}
};
本人拙见, 如有错误欢迎指出,另外代码命名很不规则,随手敲得,不好意思了
先给你解释一下,每个对象都有一个锁计数器,他保存着当前锁的owner有几个synchronized方法被调用。锁的owner每调用一个新的synchronized方法,计数器++,每次synchronized方法退出时,计数器--;计数器为0时,解锁。
这样,如果一个线程调用了synchronized方法而得锁,计数器为1,这个方法因为某些条件不满足,不能继续,用wait挂起自己,然后,其他线程有机会调用了另一个synchronized方法来满足这个条件,并且在退出前调用了notify或者notifyAll来通知刚才那个被挂起的线程,使之能继续运行。这是一般情况,但是如果这种情况,刚才那个线程在synchronized方法A中没有wait来挂起自己,而是调用了他拥有的对象的另一个方法B,满足了条件,注意,这时他拥有的对象的锁计数器为2,她调用notify,这个synchronized方法B退出之后,锁计数器变为1,所以,这个线程还有钥匙,仍然不放弃此对象,只当A也退出时,锁计数器才变为0,这个线程才松手,下面是我写的两个例子,来说明这个问题,例子一:假设Daniel是个很有钱的人,总往垃圾箱里扔东西,而Kate和Jack很穷,总去垃圾箱捡Daniel扔的东西,直到30为止,可能是垃圾箱被城管挪走了,程序结束。这是正常情况。
public class WaitNotifyTest
{
public static void main(String[] args)
{
Dustbin db = new Dustbin();
PeopleThread people1 = new PeopleThread(db, "Daniel");
PeopleThread people2 = new PeopleThread(db, "Jack");
PeopleThread people3 = new PeopleThread(db, "Kate");
people1.start();
people2.start();
people3.start();
}
}
class Dustbin
{
private int tonnage = 0;
private int operation = 0;
public boolean end()
{
return operation>30;
}
public synchronized void get(String operator)
{
int op = operation++;
System.out.println(operator + " Operation " + op + " is a get call, current tonnage is " + tonnage);
try
{
while(tonnage30;
}
public synchronized void get(String operator)
{
int op = operation++;
System.out.println(operator + " Operation " + op + " is a GET call, current tonnage is " + tonnage);
try
{
while(tonnage0.5)
dustbin.put(name);
else
dustbin.get(name);
}
}
catch (Exception e)
{System.out.println(e);}
}
};
本人拙见, 如有错误欢迎指出,另外代码命名很不规则,随手敲得,不好意思了
|
1 不是,要等到此线程主动放弃锁
2 放入锁竞争队列,排队,等待调度
2 放入锁竞争队列,排队,等待调度
|
唤醒不等于马上执行,因为现成是有优先级的。所以是排队等候的。
|
notify()是与wait()相对应的如果一个线程调用wait()永远不被唤醒则线程永远处于等候状态,但是线程被唤醒不等于说线程就开始运行,首先必须根据优先级排队等待,当然如果你的被唤醒的线程的优先级相当高则可能被唤醒后立刻运行,或者队列中没有其他的线程,你的被唤醒的线程也可能立刻运行。线程有几个状态,也叫线程的生存周期,搞清楚就好了。
您可能感兴趣的文章:
本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。