public class Main {
public static void main(String[] agrs) {
T1 t1 = new T1();
T2 t2 = new T2();
t1.start();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
t2.start();
}
public static Integer lockObj = new Integer(0);
}class T1 extends Thread {
public void run() {
synchronized(Main.lockObj) {
for (int i= 65; i< 70; ++i) {
System.out.print(String.format("%d = ", i));
try {
Main.lockObj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}class T2 extends Thread {
public void run() {
for (char i= 'A'; i< 'F'; ++i) {
synchronized(Main.lockObj) {
System.out.println(i);
Main.lockObj.notify();
}
try {
sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
上面的代码就是两个线程,如果T2不sleep的话,就不能交替执行。程序本意是T1打印一行,然后wait释放锁,T2就能获得锁,T2获得锁之后打印一行,然后notify把锁还给T1,这就出问题了,T2调notify之后并不是正在wait的T1的重新获得,因为此时T2也想获得锁,有可能又被T2获得了。所以,顺序就乱了,如果在T2里面加个延时,就对了,T2在notify之后,延时100毫秒,才能保证被T1抢过来。
解决方案 »
- 大家好!请教,如何在登录前对密码进行检测
- 急!vector的问题 java.lang.NullPointerException
- 关于java运行的简单问题
- 求救::如何在swing组件(如:jlabel)上设置一个超链接。就像html页面上的超链接一样!!
- 构造器无修饰符(default)修饰,与其他修饰符的区别是什么?
- 大虾,请帮忙分析下面程序中的static的用法
- 在JBuilder 7中时间数不能用?
- 统计一下,有多少湖南的兄弟姐妹。大家别扔。。。。我只是关心家乡。。
- 在VJ中的server-client通信中中文的传输是乱码?
- 请问怎么才能把tomcat 3.2做成NT服务?
- 在线求java项目结构组织图!!!急!!!
- (RMB)输入日期文本框,如何弹出一个日期选择的对话框,
class T1 extends Thread {
public void run() {
for (int i= 65; i< 70; ++i) {
synchronized(Main.lockObj) {
System.out.print(String.format("%d = ", i));
}
Thread.yield();
}
}
}class T2 extends Thread {
public void run() {
for (char i= 'A'; i< 'F'; ++i) {
synchronized(Main.lockObj) {
System.out.println(i);
}
Thread.yield();
}
}
}由于yield()不释放锁,所以要放在synchronized外面
对的!这个说法是准确的。notify只是唤醒了一个因为调用了wait而自愿阻塞的线程,它现在可以执行了,但是,能不能访问,要看该对该对象加锁的线程是否已经释放了锁(两种方式:第一该线程运行同步方法已经结束,第二该线程调用了wait方法,自愿阻塞)。
synchronized(obj) WaitForSingleObject(obj)
{ ..
obj.wait(); Release...()
WaitForSingleObject(obj)
} Release...()也就是说,wait应该是释放之后再重新获得,也就是分两步来的,那最后谁获得锁都不一定了
具体是那个没有保障你的需求其实可以这样思想,不需要睡眠 public static void test2() { T3 t3 = new T3();
T4 t4 = new T4();
t3.start();
t4.start();
}
public static Integer lockObj = new Integer(0);
}class T3 extends Thread {
public void run() {
try {
synchronized (Main.lockObj) {
for (int i = 65; i < 70; ++i) {
System.out.print(String.format("%d = ", i));
Main.lockObj.notify();
Main.lockObj.wait();
}
Main.lockObj.notify();//这一句很重要,不然T4的wait将没有人来唤醒
//程序会无法结束,这也表现了,在线程中切来换去
//是很危险的极易造成死锁,小心+小心
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}class T4 extends Thread {
public void run() {
try{
synchronized(Main.lockObj) {
for (char i= 'A'; i< 'F'; ++i) {
System.out.println(i);
Main.lockObj.notify();
Main.lockObj.wait();
}
}
}catch(InterruptedException e){
e.printStackTrace();
}
}
}