When a thread has yielded as a result of yield(), it releases its locks.
When a thread is sleeping as a result of sleep(), it releases its locks.这两人句话有什么不对?
对于sleep,api说不会放弃监视器,似乎是指锁,但我做了个例子,发现还是会放弃啊。到底怎么回事。public class Threads4 {
public static void main(String[] args) throws Exception{
class Mythread implements Runnable{
Threads4 t4;
Mythread(Threads4 t4) {
this.t4=t4;
} public void run() {
System.out.println("start "+Thread.currentThread().getId());
try {
t4.go();
} catch (Exception e) {
e.printStackTrace();
} System.out.println("end "+Thread.currentThread().getId());
}
}
Threads4 t4=new Threads4(); Thread t1=new Thread(new Mythread(t4));
Thread t2=new Thread(new Mythread(t4));
t1.start();
Thread.sleep(2000);
t2.start();
} public synchronized void go(){
System.out.println(Thread.currentThread().getId());
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}}
When a thread is sleeping as a result of sleep(), it releases its locks.这两人句话有什么不对?
对于sleep,api说不会放弃监视器,似乎是指锁,但我做了个例子,发现还是会放弃啊。到底怎么回事。public class Threads4 {
public static void main(String[] args) throws Exception{
class Mythread implements Runnable{
Threads4 t4;
Mythread(Threads4 t4) {
this.t4=t4;
} public void run() {
System.out.println("start "+Thread.currentThread().getId());
try {
t4.go();
} catch (Exception e) {
e.printStackTrace();
} System.out.println("end "+Thread.currentThread().getId());
}
}
Threads4 t4=new Threads4(); Thread t1=new Thread(new Mythread(t4));
Thread t2=new Thread(new Mythread(t4));
t1.start();
Thread.sleep(2000);
t2.start();
} public synchronized void go(){
System.out.println(Thread.currentThread().getId());
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}}
sleep方法是没有放弃锁的,打印完start 8之后打印8之前的那段时间就是在等待释放锁。
你的程序中你在sleep后面加一条输出语句你会看得更清楚,它到底释放锁了吗,你会看到控制台中每个go()都会连续打印两条语句
public class Threads4 {
public static void main(String[] args) throws Exception{
class Mythread implements Runnable{
Threads4 t4;
Mythread(Threads4 t4) {
this.t4=t4;
} public void run() {
t4.go();
}
}
Threads4 t4=new Threads4(); Thread t1=new Thread(new Mythread(t4));
Thread t2=new Thread(new Mythread(t4));
t1.start();
// Thread.sleep(2000);
t2.start();
} public synchronized void go(){
System.out.println("start go in thread :"+Thread.currentThread().getId());
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
} System.out.println("end go in thread :"+Thread.currentThread().getId());
}}
但是,对于yield,还有个疑问,看了http://www.diybl.com/course/3_program/java/javajs/20090407/164526.html#这篇文章,算是有了个答案,但还有个小小疑问,既然是yield用来让其它线程有机会来执行,自己放弃本次时间片。它不放弃锁怎么让其它线程来执行呢?是否yield的线程就不应该来访问同步方法,或可解释这个问题
是啊 而且书上写的也不一定对 JDK现在都7.0 beta了 以前可以重现的线程安全的错误 现在都出现不了
也就是说 书上曾经对的地方 现在也许不对了 还是自己搞搞例子 进步快啦
,但它们有很大的不同,sleep是线程类Thread 的方法,
它是使当前线程暂时睡眠,可以放在任何位置。
而wait是Object类的方法,它是使当前线程暂时放弃对象的使用权进行等待,
必须放在同步方法或同步块里。
Sleep使用的时候,线程并不会放弃对象的使用权,即不会释放对象锁,所以在同步方法或同步块中使用sleep,一个线程访问时,其他的线程也是无法访问的。
而wait是会释放对象锁的,就是当前线程放弃对象的使用权,让其他的线程可以访问。
线程执行wait方法时,需要另一个线程调用notify进行唤醒。
而sleep只是暂时休眠一定时间,时间到了之后,自动恢复运行,不需另外的线程唤醒。
如果真是这样的话,那yield()的方法的意义何在?
yield() 方法的解释之后更加疑惑了。。
yield() 使得线程放弃当前分得的 CPU 时间,但是不使线程阻塞,即线程仍处于可执行状态,随时可能再次分得 CPU 时间。调用 yield() 的效果等价于调度程序认为该线程已执行了足够的时间从而转到另一个线程。yield()只是使当前线程重新回到可执行状态,所以执行yield()的线程有可能在进入到可执行状态后马上又被执行。sleep()可使优先级低的线程得到执行的机会,当然也可以让同优先级和高优先级的线程有执行的机会;yield()只能使同优先级的线程有执行的机会。
正如楼主说的 如果具有yield()的线程进入同步代码块之后,根本就没有释放对象锁,它的效果也只等同于 wait(时间片长度) 而已。
不知道我理解是否正确。如果正确的话,那yield()有什么作用?
请高手帮忙解释下
期待。。关注