还是线程的问题。。。
javase吧
全部回复
仅看楼主
level 6
venpro 楼主
先源码
public class TT implements Runnable {
int b = 100;
public synchronized void m1() throws Exception{
b = 1000;
Thread.sleep(5000);
System.out.println("b = " + b);
}
public synchronized void m2() throws Exception {
Thread.sleep(10000);
b = 2000;
System.out.println("m2:b="+b);
}
public void run() {
try {
m1();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws Exception {
TT tt = new TT();
Thread t = new Thread(tt);
t.start();
tt.m2();
System.out.println("main:b="+tt.b);
}
}
输出结果是
m2:b=2000
main:b=1000
b = 1000
这里为什么是m2先获得的锁,明明是t.start以后再执行的m2,t.start之后不是应该马上执行run方法吗,然后就m1拿到锁?而且m2执行完应该是10秒以后了,这个时候应该m1的sleep也结束了,应该输出m1的b才是,为什么之后却是main方法里面的b输出了?
2012年05月12日 14点05分 1
level 6
venpro 楼主
public class TT implements Runnable {
int b = 100;
public synchronized void m1() throws Exception{
System.out.println("b1 = " + b);
//Thread.sleep(2000);
b = 1000;
Thread.sleep(5000);
System.out.println("b = " + b);
}
public synchronized void m2() throws Exception {
// public void m2() throws Exception {
Thread.sleep(10000);
b = 2000;
System.out.println("m2:b="+b);
}
public void run() {
System.out.println("run");
try {
System.out.println("run1");
m1();
System.out.println("run2");
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws Exception {
TT tt = new TT();
Thread t = new Thread(tt);
t.start();
tt.m2();
System.out.println("main:b="+tt.b);
Thread.sleep(10000);
}
}
改成这样以后输出
run
run1
m2:b=2000
main:b=2000
b1 = 2000
b = 1000
run2

2012年05月12日 14点05分 2
level 6
venpro 楼主
这个输出结果让我彻底晕了。
@JinCeon @JAVA小_菜_鸟 @典勇嘉谋 @pkzhou99 @itianda @情_让人迷惘 @extends_die @为悦己者容99 @__ultimate__ @学技术的某宅
你们看看,要是也没有结果,那我就先放一边了,以后再来看。

2012年05月12日 14点05分 3
level 10
我毕业答辩。。。
等别人吧。。
2012年05月12日 15点05分 4
level 6
venpro 楼主
我初步是这样的想法。这个也许跟优先级有点关系。
start方法开始后 m2也马上开始运行,由于现在的计算机速度比较快,他们几乎是同时运行的,然后m2的优先级比较高就开始运行,然后获得了锁,m1只能等,m2执行完以后m1开始运行,然后睡眠了,解然后main方法输出,再m1睡眠时间到m1输出。
2012年05月12日 15点05分 5
level 1
线程执行无顺序[打酱油]
2012年05月12日 15点05分 6
level 6
venpro 楼主
如果无顺序,那是否有机会先执行m1?
这个程序里面你无论m2 sleep多久,m2总是先执行的。
2012年05月12日 15点05分 7
level 1
用start方法来启动线程,真正实现了多线程运行,这时无需等待run方法体代码执行完毕而直接继续执行下面的代码。通过调用Thread类的start()方法来启动一个线程,这时此线程处于就绪(可运行)状态,并没有运行。 也就是说main()方法是先执行
tt.m2();
System.out.println("main:b="+tt.b); 然后运行行run()。

2012年05月12日 17点05分 8
level 6
那是因为你创建了一个新的线程对象,而实际的线程对象依然是Thread实例,而Thread类中才有sleep()方法,所以当你t.start()时,Thread.sleep(5000)才会执行,就会停5S,这时主函数继续向下执行,而tt只是调用TT这个类的一个方法而已,而TT只是实现Runnable这个接口,这个接口就只有一个run方法,所以tt.m2();肯定就不会执行Thread对象的方法,所以结果也就是那个。
简单说这就是线程对象和任务对象的解耦。
2012年05月12日 17点05分 9
level 1
我说的无顺序并不是说真的没有顺序,而是无法计算顺序。而且你这是java虚拟机,不是真正的操作系统,当几个线程同时执行时,执行速度受很多因素影响,不是你能计算得出来的。
2012年05月12日 17点05分 10
level 9
设不设置优先级都一样的,一般利用线程的唤醒机制,或者用join
2012年05月13日 00点05分 11
level 6
venpro 楼主
回复8楼: 你看看2楼我改过之后的输出,确实是先执行了run方法里面的。他应该不止是就绪。
2012年05月13日 02点05分 12
level 6
venpro 楼主
回复9楼:一楼的执行结果是先在m2里面停了10秒。
2012年05月13日 02点05分 13
level 6
你看到m2在run方法中进行调用了?
2012年05月13日 07点05分 14
level 6
去看看API中Thread这个类就知道了。
2012年05月13日 07点05分 15
level 8
[啊!]想不到竟然被召唤出来了。。。。。哥对线程了解不深哪。。。。。。
如果想要让m1()先执行,使用 wait() 和 notify() 好了.
m2(){wait();// 让m2 等待
// 原 code
}
m1(){
// 原 code
notify();// 通知m2 线程, 起床了
}
2012年05月13日 16点05分 16
level 9
[打酱油]报到一下。。
2012年05月14日 00点05分 17
level 6
修改下我上面说的。
这个问题是因为你加了同步的问题,就相当于都使用了this这个锁,所以结果就是那样。
2012年05月14日 13点05分 18
1