0

我决定面对这个叫做并发的怪物并拓宽我的线程知识,所以在我阅读 Joshua Bloch 的书之前,我决定随机编写一些代码来帮助我理解我在阅读这本书之前可能遇到的问题,希望我能来我的代码并进行更正,但后来我陷入了这个坑,我希望有人能解释一下。

我有以下内容:

public class Arithmetic implements Runnable {
    int number;    
    public  Arithmetic(int x){      
      this.number = number + x;
    }
    @Override
    public void run() {         
        Thread.currentThread().setName("thread-"+number +" > " + "number = "+getNumber());
        System.out.println(Thread.currentThread().getName());        
    }    
        public  int getNumber() {
        return number;
    }
    public  void setNumber(int number) {
        this.number = getNumber() + number;
    }
}

然后是一个主类:

public class Main {  
    public static void main(String[] args) {    
      System.out.println(Thread.currentThread().getName());     
      for (int x=0; x<=5; x++){    
           Thread thread = new Thread(new Arithmetic(x));           
           thread.start();       
      }
    }
}

有了这个,我得到以下输出:

run:
main
thread-0 > number = 0
thread-1 > number = 1
thread-2 > number = 2
thread-3 > number = 3
thread-5 > number = 5
thread-4 > number = 4

注意:5 在 4 之前

但是后来我将我的主要课程更改为:

public class Main {  
    public static void main(String[] args) {    
      System.out.println(Thread.currentThread().getName());     
      for (int x=0; x<=5; x++){    
           Runnable runnable  = new Arithmetic(x);           
          runnable.run();      
      }
    }
}

我得到下面的输出:

run:
main
thread-0 > number = 0
thread-1 > number = 1
thread-2 > number = 2
thread-3 > number = 3
thread-4 > number = 4
thread-5 > number = 5

注意:正确的顺序

我希望两个 main(s) 都会产生不稳定的结果(如线程实现),然后我会使用一些线程安全措施,如同步访问等,但为什么 Runnable 调用就像Arithmetic线程安全一样?

IMO,扩展 Thread 类和实现 Runnable 之间的区别是出于解耦目的。抱歉,如果这是一个重复的问题,我似乎找不到答案。

提前致谢。

4

4 回答 4

3

Runnables不要启动新线程它只是和接口,所以这意味着你的第二段代码同步运行。

Threads是新线程,因此您可以并行运行,这就是输出乱序的原因 - 第 4 个线程的执行速度比第 5 个慢。

于 2012-11-25T12:58:20.237 回答
2

问题是当你做

Thread t = new Thread(new Arithemetic())
 t.start();

线程t启动并执行Arithmetic

在您的情况下,您正在调用runnable.run();,这意味着当前线程将调用您的run(). 它类似于调用任何其他方法。

最终,您当前的线程本身正在执行该run方法 5 次

于 2012-11-25T12:58:36.917 回答
1

您的 Runnables 都在主线程中执行(并且在该代码中只有一个“主”线程)。

您的线程都单独执行,java 不保证一旦启动线程将以任何特定顺序执行。

于 2012-11-25T13:03:24.900 回答
0

因为Runnable它本身不在单独的线程上运行。它只是一个用于传递方法实现的接口。其中一个示例是将其传递给Thread构造函数(正如您在第一个示例中所做的那样)。因此,在您的第二个示例中,没有同时执行任何操作;它只是run()一个接一个地执行方法。

于 2012-11-25T12:59:54.137 回答