[color=brown][b][size=medium]最近温习多线程通信,所以用多线程简单模拟了交通灯,感觉自己对线程方面的东西又有了进一步的理解。[/size][/b][/color]
[b]通过这个模拟明白了notify(),与wait()又一些特点。
下面将代码贴上:[/b]
[b]交通灯类:[/b]
[b] 收获:[/b]
[size=medium][b] 1.wait()的进一步理解:如果一个线程调用了某个对象的wait方法,那么该线程进入到该对象的等待池中(并且已经将锁释放),
如果未来的某一时刻,另外一个线程调用了相同对象的notify方法或者notifyAll方法,
那么该等待池中的线程就会被唤起,然后进入到对象的锁池里面去获得该对象的锁,
如果获得锁成功后,那么该线程就会沿着wait方法之后的路径继续执行。[color=red]注意是沿着wait方法之后[/color]
[/b][/size]
[color=green][size=medium][b]2.notify()方法为唤醒同一个对象的锁。比如说a.notify()方法之能唤醒对应a.wait()方法调用的线程,而不能唤醒b.wait()对应的线程。
调用notify()方法并不代表释放当前对象的锁。它只是去通知其他线程进入到锁池里面去,而这个线程也不一定立即获的对象锁。[/b][/size][/color]
[b]通过这个模拟明白了notify(),与wait()又一些特点。
下面将代码贴上:[/b]
[b]交通灯类:[/b]
package com.xxg.entiry;
public class Light {
public int num = 20;// 南北方向和东西方向总计时间为20秒
public String color;
public Light(String color){
this.color = color;
}
public synchronized void EtoW(){
while(true){
System.out.println("东西方向等候10秒,南北方向通行");
while(num>10)
{ try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
num--;
System.out.println(num-10+"-----------[当前线程为]--------"+Thread.currentThread().getName());
}
{
while(num<=10)
{
try {
notify();
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
public synchronized void NtoS() throws InterruptedException{
while(true){
System.out.println("南北方向等候10秒,东西方向通行");
while(num>=10&&num<20)
{ try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
num++;
System.out.println(num-10+"------------[当前线程为]------------"+Thread.currentThread().getName());
}
if(num==20)
notify();
wait();
}
}
}
//======================实现控制东西方向的线程=====================
package com.xxg.inter;
import com.xxg.entiry.Light;
public class Threa1 extends Thread{
public Light light;
public Threa1(Light light) {
this.light = light;
}
public void run() {
light.EtoW();
}
}
//======================实现控制南北方法的线程=======================
package com.xxg.inter;
import com.xxg.entiry.Light;
public class Threa2 extends Thread{
public Light light;
public Threa2(Light light) {
this.light = light;
}
public void run() {
try {
light.NtoS();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
//============================Test=============================
package com.xxg.test;
import com.xxg.entiry.Light;
import com.xxg.inter.Threa1;
import com.xxg.inter.Threa2;
public class Test {
public static void main(String[] args) {
Light li = new Light("red");
Thread t1 = new Threa1(li);
Thread t2 = new Threa2(li);
t1.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
t2.start();
}
}
//=========================测试结果================================
东西方向等候10秒,南北方向通行
9-----------[当前线程为]--------Thread-0
8-----------[当前线程为]--------Thread-0
7-----------[当前线程为]--------Thread-0
6-----------[当前线程为]--------Thread-0
5-----------[当前线程为]--------Thread-0
4-----------[当前线程为]--------Thread-0
3-----------[当前线程为]--------Thread-0
2-----------[当前线程为]--------Thread-0
1-----------[当前线程为]--------Thread-0
0-----------[当前线程为]--------Thread-0
南北方向等候10秒,东西方向通行
1------------[当前线程为]------------Thread-1
2------------[当前线程为]------------Thread-1
3------------[当前线程为]------------Thread-1
4------------[当前线程为]------------Thread-1
5------------[当前线程为]------------Thread-1
6------------[当前线程为]------------Thread-1
7------------[当前线程为]------------Thread-1
8------------[当前线程为]------------Thread-1
9------------[当前线程为]------------Thread-1
10------------[当前线程为]------------Thread-1
东西方向等候10秒,南北方向通行
[b] 收获:[/b]
[size=medium][b] 1.wait()的进一步理解:如果一个线程调用了某个对象的wait方法,那么该线程进入到该对象的等待池中(并且已经将锁释放),
如果未来的某一时刻,另外一个线程调用了相同对象的notify方法或者notifyAll方法,
那么该等待池中的线程就会被唤起,然后进入到对象的锁池里面去获得该对象的锁,
如果获得锁成功后,那么该线程就会沿着wait方法之后的路径继续执行。[color=red]注意是沿着wait方法之后[/color]
[/b][/size]
[color=green][size=medium][b]2.notify()方法为唤醒同一个对象的锁。比如说a.notify()方法之能唤醒对应a.wait()方法调用的线程,而不能唤醒b.wait()对应的线程。
调用notify()方法并不代表释放当前对象的锁。它只是去通知其他线程进入到锁池里面去,而这个线程也不一定立即获的对象锁。[/b][/size][/color]