使用两个线程在循环中打印数字

时间:2015-11-11 13:51:12

标签: java multithreading

我正在尝试使用多个线程的代码。 以下是我的代码:

package com.thread.practice;

public class ThreadPratice1 {

    public static void main(String[] args) {
        MyRunnable r = new MyRunnable();
        Thread t1 = new Thread(r, "Thread 1");
        Thread t2 = new Thread(r, "Thread 2");
        t1.start();
        t2.start();
    }
}

package com.thread.practice;

public class MyRunnable implements Runnable {
    private static int i = 0;
    @Override
    public void run() {
        for(i = 0; i <10;i++){
            System.out.println("Thread: "+ Thread.currentThread().getName()
                    +" value of i: "+i);
            try {
                //System.out.println("Thread: "+ i);
                Thread.sleep(1000);
                //System.out.println("inside runnable: "+Thread.currentThread().getState());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

但是在输出中,它总是在开头两次将i的值打印为0。

输出有点像这样:

Thread: Thread 1 value of i: 0
Thread: Thread 2 value of i: 0
Thread: Thread 1 value of i: 2
Thread: Thread 2 value of i: 2
Thread: Thread 1 value of i: 3
Thread: Thread 2 value of i: 4
Thread: Thread 1 value of i: 5
Thread: Thread 2 value of i: 6
Thread: Thread 1 value of i: 7
Thread: Thread 2 value of i: 8
Thread: Thread 1 value of i: 9

请有人帮助我理解这个问题吗?

4 个答案:

答案 0 :(得分:2)

因为执行两个线程时i的值为0

换句话说,线程1和线程2几乎同时盯着,所以他们两个为第一个循环设置i为0。

for(i = 0; i <10;i++) {

然后,线程之间的值会发生变化,因为您将i设置为静态。所以它将在你的两个线程之间共享。

答案 1 :(得分:2)

你做了#34;我&#34; static,这意味着它将在所有线程和对象上相同。拿走静态修改器,你的代码就能正常工作。

编辑:我误解了你的问题 - 在for循环中没有将i设置为0,它看起来像这样:

for(;i<10;i++) { /*mycode*/}

这两个中的一个可能是你想要的,你的问题有点模糊

答案 2 :(得分:0)

只有在执行循环后,才会使for循环增加

i的值。执行for循环需要有限的时间。由于您(几乎)一起启动线程,因此在另一个线程完成一个循环后,两个线程可能会也可能不会打印i。因为你没有做到确保线程安全,所以结果将像你得到的那样无法预测。

答案 3 :(得分:0)

首先,您不应该使用原始 int 类型进行并发,它不是线程安全的,它可能会导致Race Condition

并尝试使用AtomicInteger替换int,它的线程安全。例子可能是:

public class ThreadPratice1 {

    public static void main(String[] args) {
        AtomicInteger number = new AtomicInteger(0);
        MyRunnable r = new MyRunnable(number);
        Thread t1 = new Thread(r, "Thread 1");
        Thread t2 = new Thread(r, "Thread 2");
        t1.start();
        t2.start();
    }
}

class MyRunnable implements Runnable {
    private AtomicInteger number;

    public MyRunnable(AtomicInteger number) {
        this.number = number;
    }

    @Override
    public void run() {
        while (number.get() < 10) {
            System.out.println("Thread: " + Thread.currentThread().getName()
                    + " value of i: " + number.getAndIncrement());
        }
    }
}