程序代码如下:
import java.lang.Runnable;
import java.lang.Thread;public class DemoThread implements Runnable {
public DemoThread() {
TestThread testthread1 = new TestThread(this, "1");
TestThread testthread2 = new TestThread(this, "2");
testthread2.start();
testthread1.start();
}
public static void main(String[] args) {
DemoThread demoThread1 = new DemoThread();
}
public void run() {
TestThread t = (TestThread) Thread.currentThread();
try {
if (!t.getName().equalsIgnoreCase("1")) {
synchronized (this) {
wait();
}
}
while (true) {
System.out.println("@time in thread" + t.getName() + "="+ t.increaseTime());
if (t.getTime() % 10 == 0) {
synchronized (this) {
System.out.println ("****************************************");
notify();
if (t.getTime() == 100) {
break;
}
wait();
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}class TestThread extends Thread {
private int time = 0;
public TestThread(Runnable r, String name) {
super(r, name);
}
public int getTime() {
return time;
}
public int increaseTime() {
return ++time;
}
}
代码中两次用到了wait,一次用到了notiy,请问他们的作用分别是如何来控制线程的呢
import java.lang.Runnable;
import java.lang.Thread;public class DemoThread implements Runnable {
public DemoThread() {
TestThread testthread1 = new TestThread(this, "1");
TestThread testthread2 = new TestThread(this, "2");
testthread2.start();
testthread1.start();
}
public static void main(String[] args) {
DemoThread demoThread1 = new DemoThread();
}
public void run() {
TestThread t = (TestThread) Thread.currentThread();
try {
if (!t.getName().equalsIgnoreCase("1")) {
synchronized (this) {
wait();
}
}
while (true) {
System.out.println("@time in thread" + t.getName() + "="+ t.increaseTime());
if (t.getTime() % 10 == 0) {
synchronized (this) {
System.out.println ("****************************************");
notify();
if (t.getTime() == 100) {
break;
}
wait();
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}class TestThread extends Thread {
private int time = 0;
public TestThread(Runnable r, String name) {
super(r, name);
}
public int getTime() {
return time;
}
public int increaseTime() {
return ++time;
}
}
代码中两次用到了wait,一次用到了notiy,请问他们的作用分别是如何来控制线程的呢
代码块的执行权,就意味着它锁定了监视器。在一个时间内,只能有一个线程可以锁定监视器。所以其他的线
程在试图进入监视器前都将被挂起,直到锁定了监视器的线程执行完毕,监视器被解锁。并且一个刚锁定了
监视器的线程被解锁后,可以马上再次进入并锁定同一监视器。有了监视器的概念,再来看看下面几个方法
的含义:
wait:告诉当前线程放弃监视器并进入睡眠状态,直到其他线程进入同一监视器并调用notify为止。
notify:唤醒同一对象监视器中调用wait的第一个线程。用于类似饭馆有一个空位后通知所有等候就餐
的顾客中的第一位可以入坐的情况。
notifyAll:唤醒同一对象监视器中调用wait的所有线程,具有最高优先级别的线程首先被唤醒并执行。
用于某个不定期的培训班终于招生满额后,通知所有学员来上课的情况,先到达的,会先安排住宿。
wait()执行完后,释放demoThread1对象的锁,test2线程因为名字不是1而直接进入while循环,在循环中,每次time值加1,当加到10的整数倍的时候,test2线程执行notify,这里相当与this.notify, 也就是demoThread1.notify(),作用是告诉在demoThread1对象等待区中的线程:你们不用等了,可以出来了。在这里的效果就是test2让先前的test1恢复执行,然后test2调用wait()让自己进入demoThread1的等待区,接下来的事情就是test1和test2互相调换角色,直到两个线程的计数达到100,线程结束。
在一个DemoThread对象中启动了两个线程test1和test2,test1在刚进入run的时候就会开始等待,在这里真正发生的事情是test1进入了DemoThread对象的等待区,在JAVA中任何一个对象都有自己的等待区(这也是为什么wait(),notify()和notifyAll()是Object类的方法而不是Thread类的方法的原因)。这里的wait()相当与this.wait(),效果和demoThread1.wait()一样,意思是执行wait()方法的这个线程test1要进入调用这个wait()方法的对象demoThread1的等待区了!!!
wait()执行完后,释放demoThread1对象的锁,test2线程因为名字不是1而直接进入while循环,在循环中,每次time值加1,当加到10的整数倍的时候,test2线程执行notify,这里相当与this.notify, 也就是demoThread1.notify(),作用是告诉在demoThread1对象等待区中的线程:你们不用等了,可以出来了。在这里的效果就是test2让先前的test1恢复执行,然后test2调用wait()让自己进入demoThread1的等待区,接下来的事情就是test1和test2互相调换角色,直到两个线程的计数达到100,线程结束。
================================================================================== LBN1012(星空)说的不对,因为先调用了“testthread2.start();”。所以test2先执行,不过在遇到(!t.getName().equalsIgnoreCase("1")) 条件时,test2符合条件,所以就执行wait(),进入demoThread1的等待队列了。然后,就是test1执行,它不符合(!t.getName().equalsIgnoreCase("1")) 条件,所以跳过,继续下面的,也就是while (true) { … }中的循环,当test1在循环体中反复执行了10次,也就是test1对象中time等于10时,demoThread1.notify()被执行,notify()让demoThread1对象的等待队列中第一个线程也就是test2结束等待,进入就绪状态。最后,wait()被执行,demoThread1对象把test1放入等待队列。
下面就是在就绪状态test2进入运行状态了,注意它不是重头从run()方法开始执行,而是从上次被阻塞的地方开始,继续向下执行……
再接下来的事情就是test1和test2互相替换执行。LBN1012(星空)说的还是很清晰易懂的,大概是熬夜的原因吧,没看到条件前有“!”。
顺便说一下,这段代码中if (!t.getName().equalsIgnoreCase("1")) {
synchronized (this) {
wait();
}
}
才是亮点,如果没有它,程序就有一定的几率出问题。
两个线程都是对自己搞同步锁,有什么“交替执行”