public class Test2 implements Runnable{
int b = 100;
public synchronized void m1() throws InterruptedException {
System.out.println("m1 is start");
b = 1000;
//Thread.sleep(5000);
System.out.println("m1.b="+b);
}
public synchronized void m2() throws InterruptedException { //去除synchronized后就是输出2000
System.out.println("m2 is start");
Thread.sleep(2000);
b=2000;
System.out.println("m2 is over");
}
public void run(){
try {
m1();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws InterruptedException {
Test2 tt = new Test2();
Thread t = new Thread(tt);
t.start();
tt.m2();
System.out.println("main.b="+tt.b);
}
}
为什么tt.m2()一定会优先于run()方法调用的m1()方法呢?求大神
24 个解决方案
#1
不一定,先多测试试试
如果一直是tt.m2()一定会优先于run()方法调用的m1()方法,那可能是java线程调度器的影响具体就不知道了
如果一直是tt.m2()一定会优先于run()方法调用的m1()方法,那可能是java线程调度器的影响具体就不知道了
#2
谢谢,是确定了m2先执行,还是很感谢你用心的回答!
#3
刚刚问了下老师,应该是你后面说的那个问题
#4
main方法 代表的是主线程的 他的优先度好像要高一点
如果你在里面创建多个线程 他们则是同级的
#5
#6
只是因为main线程先于Test2抢到了执行权
#7
我之前也是这么想的,我老师后来用debug调试,成了m1先执行了
#8
#9
优先级高不一定先执行
#10
优先级高不一定先执行 main方法 代表的是主线程的 他的优先度好像要高一点 如果你在里面创建多个线程 他们则是同级的
我之前也是这么想的,我老师后来用debug调试,成了m1先执行了
也是哦,我之前是想的最开始的一瞬间是主函数的先进行
#11
Thread.yield()
理解了这个方法,你就理解你现在问的这个问题了。
理解了这个方法,你就理解你现在问的这个问题了。
#12
调用start之后,线程只是处于等待调度的“就绪”状态,并没有启动。调试多线程最好用日志,调试器要么只暂停一个线程,要么全部挂起,容易让人困扰的。
#13
#14
"在HotSpot VM上,按照链接里的代码的写法,其实tt.m2()几乎总是会比Test2.run()要更早被调用,因为Thread.start()在调用(caller)线程上创建好线程就返回了,紧接着就可以去调用执行tt.m2();而在被调用(callee)的新线程上还要经过一些JVM内部的初始化动作才能跑到您指定的入口方法(这里就是Thread.run() -> Runnable.run() -> Test2.run())。<br>这并不是Java语言规范或者JVM规范所要求的行为,只是在HotSpot VM这种特定实现上会有这样的特征,所以既不应该当作标准行为去依赖,也不要因为规范没要求而拒绝承认实现中有这样的特征。"谢谢,结贴
#15
只是因为main线程先于Test2抢到了执行权
#16
不一定,先多测试试试
如果一直是tt.m2()一定会优先于run()方法调用的m1()方法,那可能是java线程调度器的影响具体就不知道了
刚刚问了下老师,应该是你后面说的那个问题
如果一直是tt.m2()一定会优先于run()方法调用的m1()方法,那可能是java线程调度器的影响具体就不知道了
刚刚问了下老师,应该是你后面说的那个问题
#17
我觉得可以这样理解,不知道对不对,在程序运行时,主线程已经启动并在运行中,而你另外起一个线程start表示线程处于就绪状态,还要等JVM机制调用进入运行状态,所以一般来讲这种简单的程序主线程执行的要快一些
#18
main方法是一个线程
然后你
Test2 tt = new Test2();
Thread t = new Thread(tt);
t.start();
tt.m2();
这代码的意思是
t.start新起一个线程去运行run方法
但是对main这个线程来说
他会继续往下走 执行tt.m2
一个是新起线程去执行
一个是在本线程执行
当然是m2快
至于调试的时候因为你把main的线程给挂起来了
而影响不到新起来的run线程
所以run先跑
然后你
Test2 tt = new Test2();
Thread t = new Thread(tt);
t.start();
tt.m2();
这代码的意思是
t.start新起一个线程去运行run方法
但是对main这个线程来说
他会继续往下走 执行tt.m2
一个是新起线程去执行
一个是在本线程执行
当然是m2快
至于调试的时候因为你把main的线程给挂起来了
而影响不到新起来的run线程
所以run先跑
#19
"在HotSpot VM上,按照链接里的代码的写法,其实tt.m2()几乎总是会比Test2.run()要更早被调用,因为Thread.start()在调用(caller)线程上创建好线程就返回了,紧接着就可以去调用执行tt.m2();而在被调用(callee)的新线程上还要经过一些JVM内部的初始化动作才能跑到您指定的入口方法(这里就是Thread.run() -> Runnable.run() -> Test2.run())。<br>这并不是Java语言规范或者JVM规范所要求的行为,只是在HotSpot VM这种特定实现上会有这样的特征,所以既不应该当作标准行为去依赖,也不要因为规范没要求而拒绝承认实现中有这样的特征。"谢谢,结贴
#20
java线程,正在学习,谢谢分享。
#21
learning~
#22
你在另外一个类里面测试一下
#23
"在HotSpot VM上,按照链接里的代码的写法,其实tt.m2()几乎总是会比Test2.run()要更早被调用,因为Thread.start()在调用(caller)线程上创建好线程就返回了,紧接着就可以去调用执行tt.m2();而在被调用(callee)的新线程上还要经过一些JVM内部的初始化动作才能跑到您指定的入口方法(这里就是Thread.run() -> Runnable.run() -> Test2.run())。<br>这并不是Java语言规范或者JVM规范所要求的行为,只是在HotSpot VM这种特定实现上会有这样的特征,所以既不应该当作标准行为去依赖,也不要因为规范没要求而拒绝承认实现中有这样的特征。"谢谢,结贴
这个解释真的很赞。建议楼主尝试试用一下yield:
这样出来的结果就未必总是tt.m2()先执行了。
public static void main(String[] args) throws InterruptedException {
Test2 tt = new Test2();
Thread t = new Thread(tt);
t.start();
Thread.yield();
tt.m2();
System.out.println("main.b="+tt.b);
}
#24
感谢大神们的分享
#1
不一定,先多测试试试
如果一直是tt.m2()一定会优先于run()方法调用的m1()方法,那可能是java线程调度器的影响具体就不知道了
如果一直是tt.m2()一定会优先于run()方法调用的m1()方法,那可能是java线程调度器的影响具体就不知道了
#2
不一定,先多测试试试
如果一直是tt.m2()一定会优先于run()方法调用的m1()方法,那可能是java线程调度器的影响具体就不知道了
谢谢,是确定了m2先执行,还是很感谢你用心的回答!
#3
不一定,先多测试试试
如果一直是tt.m2()一定会优先于run()方法调用的m1()方法,那可能是java线程调度器的影响具体就不知道了
刚刚问了下老师,应该是你后面说的那个问题
#4
main方法 代表的是主线程的 他的优先度好像要高一点
如果你在里面创建多个线程 他们则是同级的
#5
#6
只是因为main线程先于Test2抢到了执行权
#7
main方法 代表的是主线程的 他的优先度好像要高一点 如果你在里面创建多个线程 他们则是同级的
我之前也是这么想的,我老师后来用debug调试,成了m1先执行了
#8
#9
main方法 代表的是主线程的 他的优先度好像要高一点 如果你在里面创建多个线程 他们则是同级的
我之前也是这么想的,我老师后来用debug调试,成了m1先执行了
#10
优先级高不一定先执行 main方法 代表的是主线程的 他的优先度好像要高一点 如果你在里面创建多个线程 他们则是同级的
我之前也是这么想的,我老师后来用debug调试,成了m1先执行了
也是哦,我之前是想的最开始的一瞬间是主函数的先进行
#11
Thread.yield()
理解了这个方法,你就理解你现在问的这个问题了。
理解了这个方法,你就理解你现在问的这个问题了。
#12
调用start之后,线程只是处于等待调度的“就绪”状态,并没有启动。调试多线程最好用日志,调试器要么只暂停一个线程,要么全部挂起,容易让人困扰的。
#13
#14
"在HotSpot VM上,按照链接里的代码的写法,其实tt.m2()几乎总是会比Test2.run()要更早被调用,因为Thread.start()在调用(caller)线程上创建好线程就返回了,紧接着就可以去调用执行tt.m2();而在被调用(callee)的新线程上还要经过一些JVM内部的初始化动作才能跑到您指定的入口方法(这里就是Thread.run() -> Runnable.run() -> Test2.run())。<br>这并不是Java语言规范或者JVM规范所要求的行为,只是在HotSpot VM这种特定实现上会有这样的特征,所以既不应该当作标准行为去依赖,也不要因为规范没要求而拒绝承认实现中有这样的特征。"谢谢,结贴
#15
只是因为main线程先于Test2抢到了执行权
#16
不一定,先多测试试试
如果一直是tt.m2()一定会优先于run()方法调用的m1()方法,那可能是java线程调度器的影响具体就不知道了
刚刚问了下老师,应该是你后面说的那个问题
如果一直是tt.m2()一定会优先于run()方法调用的m1()方法,那可能是java线程调度器的影响具体就不知道了
刚刚问了下老师,应该是你后面说的那个问题
#17
我觉得可以这样理解,不知道对不对,在程序运行时,主线程已经启动并在运行中,而你另外起一个线程start表示线程处于就绪状态,还要等JVM机制调用进入运行状态,所以一般来讲这种简单的程序主线程执行的要快一些
#18
main方法是一个线程
然后你
Test2 tt = new Test2();
Thread t = new Thread(tt);
t.start();
tt.m2();
这代码的意思是
t.start新起一个线程去运行run方法
但是对main这个线程来说
他会继续往下走 执行tt.m2
一个是新起线程去执行
一个是在本线程执行
当然是m2快
至于调试的时候因为你把main的线程给挂起来了
而影响不到新起来的run线程
所以run先跑
然后你
Test2 tt = new Test2();
Thread t = new Thread(tt);
t.start();
tt.m2();
这代码的意思是
t.start新起一个线程去运行run方法
但是对main这个线程来说
他会继续往下走 执行tt.m2
一个是新起线程去执行
一个是在本线程执行
当然是m2快
至于调试的时候因为你把main的线程给挂起来了
而影响不到新起来的run线程
所以run先跑
#19
"在HotSpot VM上,按照链接里的代码的写法,其实tt.m2()几乎总是会比Test2.run()要更早被调用,因为Thread.start()在调用(caller)线程上创建好线程就返回了,紧接着就可以去调用执行tt.m2();而在被调用(callee)的新线程上还要经过一些JVM内部的初始化动作才能跑到您指定的入口方法(这里就是Thread.run() -> Runnable.run() -> Test2.run())。<br>这并不是Java语言规范或者JVM规范所要求的行为,只是在HotSpot VM这种特定实现上会有这样的特征,所以既不应该当作标准行为去依赖,也不要因为规范没要求而拒绝承认实现中有这样的特征。"谢谢,结贴
#20
java线程,正在学习,谢谢分享。
#21
learning~
#22
你在另外一个类里面测试一下
#23
"在HotSpot VM上,按照链接里的代码的写法,其实tt.m2()几乎总是会比Test2.run()要更早被调用,因为Thread.start()在调用(caller)线程上创建好线程就返回了,紧接着就可以去调用执行tt.m2();而在被调用(callee)的新线程上还要经过一些JVM内部的初始化动作才能跑到您指定的入口方法(这里就是Thread.run() -> Runnable.run() -> Test2.run())。<br>这并不是Java语言规范或者JVM规范所要求的行为,只是在HotSpot VM这种特定实现上会有这样的特征,所以既不应该当作标准行为去依赖,也不要因为规范没要求而拒绝承认实现中有这样的特征。"谢谢,结贴
这个解释真的很赞。建议楼主尝试试用一下yield:
这样出来的结果就未必总是tt.m2()先执行了。
public static void main(String[] args) throws InterruptedException {
Test2 tt = new Test2();
Thread t = new Thread(tt);
t.start();
Thread.yield();
tt.m2();
System.out.println("main.b="+tt.b);
}
#24
感谢大神们的分享