2 u014562113 u014562113 于 2016.02.18 19:00 提问

有一道Java面试题,没太理解明白,求大神指点啊~

package test2;
/**

  • 设计4个线程,其中两个线程每次对i增加1,另外两个线程对i每次减少1
  • @author liuyu
    *
    */
    public class Test {

    private int i ;

    private synchronized void inc(){

    i ++;

    System. out .println(Thread.currentThread().getName()+ "--inc--" + i );

    }

    private synchronized void dec(){

    i --;

    System. out .println(Thread.currentThread().getName()+ "--dec--" + i );

    }

    class Inc implements Runnable {

    public void run() {

    inc();

    }

    }

    class Dec extends Thread{

    public void run() {

    dec();

    }

    }

    public static void main(String[] args) {

    Test t = new Test();

    Inc inc = t. new Inc();

    Thread thread = null;

    // 创建 2 个增加线程

    for ( int i = 0; i < 2; i++) {

    thread = new Thread(inc);

    thread.start();

    }

    // 创建 2 个减少线程

    for ( int i = 0; i < 2; i++) {

    thread = t.new Dec();

    thread.start();

    }

    }

    }

输出:Thread-0--inc--1
Thread-3--dec--0
Thread-2--dec---1
Thread-1--inc--0

可是我感觉应该输出是:
Thread-0--inc--1
Thread-1--inc--2
Thread-2--dec--1
Thread-3--dec--0

因为按照执行顺序,当执行第一个for循环第一次的时候创建第一个线程,并且i加1,执行第二次for循环的时候i再加1等于2;
执行第二个for循环的时候,创建第三个线程,并且i减1,执行第二次的后事i再减1等于0

为什么不对呢?

8个回答

luochoudan
luochoudan   Ds   Rxr 2016.02.18 23:06
已采纳

卤煮的想法没错,程序确实是一步一步从上往下执行的,也创建了四个线程,之所以没有出现预期的结果,可能是有一点被忽略了,java中的线程有自己的生命周期,一个新的线程会经历创建、就绪然后才能进入执行状态。也就是说你的程序创建了四个线程,它们只是进入了就绪状态,等待cpu线程栈的调度,而何时可以得执行以及执行的顺序还要依赖cpu的性能、cpu的个数等等。所以程序的输出结果应该是未知的,卤煮可以多跑几次,应该会输出不同内容。嘿嘿。

u014562113
u014562113 谢谢,您说的有道理,理解了。
接近 2 年之前 回复
devmiao
devmiao   Ds   Rxr 2016.02.18 19:15
zydarbo
zydarbo   2016.02.18 20:31

这是不是跟线程状态有关系呢?
你只是把线程start了,并不是直接计算了,可能当时线程并没有开始计算。
如果多调用几次应该每次结果都不一样吧?
我只是提供个思路,毕竟我也不是很清楚。sorry

Mr_dsw
Mr_dsw   Ds   Rxr 2016.02.18 20:58

这个你应该能搜到,讲解的就是java的线程同步问题,很经典的套路

u014562113
u014562113   2016.02.18 21:25

我知道例子,我想问的是 为什么每次执行结果顺序不一样呢?我想问的是这个 ,继续求解答,,

fanst_
fanst_   2016.02.18 22:42

四个线程的启动可以认为是同时发生的(间隔时间非常短),线程并发并不代表线程会同时执行(可以百度下并发和并行的区别)。
CPU个数是限制,例如在单核CPU上,同一时间只能将cpu分配给某一个线程执行,这就是所谓的资源竞争,而竞争的结果不一定是相同的。
所以四个线程执行顺序不可预期。

henuyx
henuyx   2016.02.19 10:59

cpu执行哪个,是有时间片的,虽然创建了一个线程,但是线程并不一定会立即被cpu运行,所以可能在等待时间片。
所以也不一定结果就是 1 0 1 0,也有可能是 1 2 1 0
你要想输出结果一定,就需要做线程的同步,保证某个线程先执行,另外一个线程再执行

qdp228
qdp228   2016.02.19 15:28

是的,从程序流程来看,该是你说的结果。但是,线程创建、启动后,并不是马上就执行你的业务逻辑,至于哪个先执行,是需要进行调度的,由于不确定性,结果也是会不一样的。可以借助线程的join()或者优先级等,来提高优先执行顺序,以达到预期效果。

Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!