看下面的程序:
public class TT implements Runnable{
int b = 100;
public synchronized void m1() throws Exception{
//System.out.println("m1 start...");
b = 1000;
Thread.sleep(5000);
System.out.println("b = " + b);
//System.out.println("m1 end...");
}
public synchronized void m2() throws InterruptedException{
//System.out.println("m2 start...");
Thread.sleep(2000);
b = 2500;
//System.out.println("m2 end...");
}
public void run() {
//System.out.println("run start...");
try{
m1();
}catch(Exception e){
e.printStackTrace();
}
//System.out.println("run end...");
}
public static void main(String[] args) throws InterruptedException {
TT tt = new TT();
Thread t = new Thread(tt);
t.start();
tt.m2();
System.out.println(tt.b);
}
}假如没有把注释的东西注释掉,结果又是如何?还有结果是不是唯一?
public class TT implements Runnable{
int b = 100;
public synchronized void m1() throws Exception{
//System.out.println("m1 start...");
b = 1000;
Thread.sleep(5000);
System.out.println("b = " + b);
//System.out.println("m1 end...");
}
public synchronized void m2() throws InterruptedException{
//System.out.println("m2 start...");
Thread.sleep(2000);
b = 2500;
//System.out.println("m2 end...");
}
public void run() {
//System.out.println("run start...");
try{
m1();
}catch(Exception e){
e.printStackTrace();
}
//System.out.println("run end...");
}
public static void main(String[] args) throws InterruptedException {
TT tt = new TT();
Thread t = new Thread(tt);
t.start();
tt.m2();
System.out.println(tt.b);
}
}假如没有把注释的东西注释掉,结果又是如何?还有结果是不是唯一?
http://topic.csdn.net/u/20090421/22/16f06a01-9688-4dc8-9352-62c82c6adfb5.html
int b = 100; public synchronized void m1() throws Exception{
//System.out.println("m1 start...");
b = 1000;
Thread.sleep(5000);
System.out.println("b = " + b);
//System.out.println("m1 end...");
} public synchronized void m2() throws InterruptedException{
//System.out.println("m2 start...");
Thread.sleep(2000);
b = 2500;
//System.out.println("m2 end...");
} public void run() {
//System.out.println("run start...");
try{
m1();
}catch(Exception e){
e.printStackTrace();
}
//System.out.println("run end...");
} public static void main(String[] args) throws InterruptedException {
TT tt = new TT();
Thread t = new Thread(tt);
t.start(); tt.m2();
System.out.println(tt.b);
}
}
假如没有把注释的东西注释掉,结果又是如何?还有结果是不是唯一?
public class TT implements Runnable{
int b = 100; public void m1() throws Exception{
//System.out.println("m1 start...");
b = 1000;
Thread.sleep(5000);
System.out.println("b = " + b);
//System.out.println("m1 end...");
} public void m2() throws InterruptedException{
//System.out.println("m2 start...");
Thread.sleep(2000);
b = 2500;
//System.out.println("m2 end...");
} public void run() {
//System.out.println("run start...");
try{
m1();
}catch(Exception e){
e.printStackTrace();
}
//System.out.println("run end...");
} public static void main(String[] args) throws InterruptedException {
TT tt = new TT();
Thread t = new Thread(tt);
t.start(); tt.m2();
System.out.println(tt.b);
}
}
run start... m2 start...
m1 start... m1 start...
m2 end... m2 end...
2500 2500
b = 2500 b = 2500
m1 end... m1 end...
run end... run end...
我觉得只可能出上面两种结果
D:\tomcat5.5.17\webapps\ch4\WEB-INF\classes>javac TT.javaD:\tomcat5.5.17\webapps\ch4\WEB-INF\classes>java TT
2500
b = 2500D:\tomcat5.5.17\webapps\ch4\WEB-INF\classes>javac ATT.javaD:\tomcat5.5.17\webapps\ch4\WEB-INF\classes>java ATT
2500
b = 2500D:\tomcat5.5.17\webapps\ch4\WEB-INF\classes>javac ATT.javaD:\tomcat5.5.17\webapps\ch4\WEB-INF\classes>java TT
2500
b = 2500
run start...
m1 start...
m2 end...
2500
b = 2500
m1 end...
run end...
b = 2500
一种情况,
因为无论线程以什么顺序执行,m2 sleep的时间远低于m1的sleep时间,
所以等线程苏醒的时候,m2肯定已经被执行了,b总是2500.
但如果去掉注释,那么
最后
b = 2500
这个结果不会变,
但其它调试信息的顺序,会有好多种可能性:
不少于4种。
run start...
m1 start...
m2 end...
2500
b = 2500
m1 end...
run end...
多线程,并不是指多个线程在同一个时间同时运行。它只是利用操作系统的时间片轮转的功能。
先运行这个线程几秒,然后停在,再去运行另一个线程。只是时间分的很快,让我们感觉到这
几个线程是同时运行的。
当程序运行时,执行的是main这个线程。当开启t这个新线程的时候,main这个线程的时间片
还没有完成,所以它接着执行。当它sleep的时候,t 的新线程得到了运行的机会这时b=1000.接着
2秒过去了,main又得到了运行机会,将b设成2500,然后打印输出System.out.println(tt.b)。这时
main的线程结束了。之后t接着运行,直到结束。
对于你说的第一种情况: 你是如何确保子线程中的m1()方法中的语句:b = 1000; 这条语句是在是m2()执行完后再执行还是在先执行这条语句再执行方法m2()的。对于你说的第二种情况: 你没有自己运行程序看一下吗?
依据在于:无论怎样,两个方法的sleep有3秒钟差距,CPU在三秒之内不执行不到b=1000的可能性,可以说为0.对于你说的第二种情况: 你没有自己运行程序看一下吗? 多线程的各种调度情况,执行一两次不可能得到所有结果,多数是相同的结果。
但只要执行的次数足够多,一定会出现不一样的调度顺序。所以,只是做理论验证而已。
我认为这句话是理论性的,虽然可能性小,但是是有可能的
厉害啊!!!!!!!如果有了synchronized,那么结果就大大不同了。
public class TT implements Runnable {
int b = 100; public synchronized void m1() throws Exception {
// System.out.println("m1 start...");
b = 1000;
Thread.sleep(5000);
System.out.println("b = " + b);
// System.out.println("m1 end...");
} public synchronized void m2() throws InterruptedException {
// System.out.println("m2 start...");
Thread.sleep(2000);
b = 2500;
// System.out.println("m2 end...");
} public void run() {
// System.out.println("run start...");
try {
m1();
} catch (Exception e) {
e.printStackTrace();
}
// System.out.println("run end...");
} public static void main(String[] args) throws InterruptedException {
TT tt = new TT();
Thread t = new Thread(tt);
t.start(); tt.m2();
System.out.println(tt.b);
}
}运行结果:
1000
b = 1000在也没有其他的输出了
2500
b = 1000
或者
1000
b = 1000 synchronized aMethod(){}可以防止多个线程同时访问这个对象的synchronized方法(如果一个对象有多个synchronized方法,只要一个线程访问了其中的一个synchronized方法,其它线程不能同时访问这个对象中任何一个synchronized方法)
要么M1先执行完,再执行M2,
或者反过来。但实际上,由于m2在主线程中,通常会比新的线程更容易抢占CPU,
所以出b=1000的概率大的多。
TT tt = new TT();
Thread t = new Thread(tt);
t.start();tt.m2(); //调用的是TT方法不是run
System.out.println(tt.b);
}
}
在执行System.out.println(tt.b);后
t.start 还没执行完
打印出的就是int b = 100;等t.start() 结束后
main线程才结束()可以在tt.m2(); 后添加让主线程sleep更长时间
在看看结果....
执行System.out.println(tt.b);
t.start还没有执行完,这个我赞成,但是它执行到那了?为什么大部分都是在执行了 Thread.sleep(2000);
b = 2500;后再执行 b = 1000;
我相信大家得到的结果基本上都是:
1000
b = 1000
1000
b = 1000
不可能有别的结果~我认为运行情况是这样的:
t.start(); //主线程开始运行tt.m2(); //调用的是TT方法不是run
System.out.println(tt.b);
}
}
但是由于m2()方法的时间短于m1()方法,先是m2()方法调用完,打印了System.out.println(tt.b); 这个值,然后再执行主线程的方法,所以就打印了m1()方法的值。
我们可以肯定的main方法中的语句执行顺序如下:
TT tt = new TT();
Thread t = new Thread(tt);
t.start();
tt.m2();
System.out.println(tt.b);
但调用了t.start()方法,并不意味着t线程会立即执行,这只是将t线程加入了等待队列中,
1、有可能先执行tt.m2()方法,再执行t线程,
2、也有可能先执行t线程,再执行tt.m2()方法
但由于又加入了synchronized关键字,就有会使m1和m2方法不会同时执行,但执行的先后顺序很难预料,至于打印的结果更难预料。
34楼,先是m2()方法先调用完,打印了System.out.println(tt.b); 结果是多少?是2500吧?为何结果是1000?你没有解释啊..
int b = 100; public void m1() throws Exception{
//System.out.println("m1 start...");
b = 1000;
Thread.sleep(5000);
System.out.println("b = " + b);
//System.out.println("m1 end...");
} public void m2() throws InterruptedException{
//System.out.println("m2 start...");
Thread.sleep(2000);
b = 2500;
//System.out.println("m2 end...");
} public void run() {
//System.out.println("run start...");
try{
m1();
}catch(Exception e){
e.printStackTrace();
}
//System.out.println("run end...");
} public static void main(String[] args) throws InterruptedException {
TT tt = new TT();
Thread t = new Thread(tt);
t.start(); tt.m2();
System.out.println(tt.b);
}
}