Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用线程打印数字序列而不进行任何同步_Java_Multithreading - Fatal编程技术网

Java 使用线程打印数字序列而不进行任何同步

Java 使用线程打印数字序列而不进行任何同步,java,multithreading,Java,Multithreading,我试图写一个简单的代码来按顺序打印数字。情况就像 1 2 3 4 5 .. and so on 这是我写的代码 public class CounterThread implements Runnable { int counterNumber; public CounterThread(int counterNumber) { this.counterNumber = counterNumber; } @Override publ

我试图写一个简单的代码来按顺序打印数字。情况就像

1
2
3
4
5
.. and so on 
这是我写的代码

public class CounterThread implements Runnable {
    int counterNumber;

    public CounterThread(int counterNumber) {
        this.counterNumber = counterNumber;
    }

    @Override
    public void run() {
        System.out.println(this.counterNumber);
    }


    public static void main(String[] args) throws InterruptedException {
        int number = Integer.parseInt(args[0]);
        Thread[] listOfThreads = new Thread[number];
        for(int i = 1; i <= number; i++){
            CounterThread counterThread = new CounterThread(i);
            Thread thread = new Thread(counterThread);
            thread.start();
            listOfThreads[i-1] = thread;
        }

        for(Thread thread : listOfThreads){
            thread.join();
        }
    }
}
        

公共类计数器线程实现可运行{
整数计数器;
公共计数器线程(int计数器编号){
this.counterNumber=计数器编号;
}
@凌驾
公开募捐{
System.out.println(此计数器编号);
}
公共静态void main(字符串[]args)引发InterruptedException{
int number=Integer.parseInt(args[0]);
线程[]列表线程=新线程[编号];

对于(inti=1;i您可以通过编写此代码来优化代码,它只会使主线程等待当前
线程
完成其执行

for (int i = 1; i <= number; i++) {
    CounterThread counterThread = new CounterThread(i);
    Thread thread = new Thread(counterThread);
    thread.start();
    thread.join();
}
但您应该注意,
volatile
并不能100%保证您将避免竞争条件。特别是在这种情况下,因为
number++
将不是一个原子操作。它实际上是
number=number+1
-一读一写

但是使用
Atomic
,递增将是一个原子操作,您可以编写如下代码

AtomicInteger number = new AtomicInteger(0);

...

@Override
public void run() {
    System.out.println(number.incrementAndGet());
}

您只需在
start()
之后调用
join()
,因为第一个循环中方法的开始会导致它执行,并且在到达下一个循环之前,它已经完成了工作,所以您需要在开始后的第一个循环中调用它,以确保在开始下一个循环之前结束它:

join()方法,允许一个线程等待另一个线程完成其执行。如果t是线程当前正在执行的线程对象,则t.join()将确保在程序执行下一条指令之前终止t

公共类计数器线程实现可运行{
整数计数器;
公共计数器线程(int计数器编号){
this.counterNumber=计数器编号;
}
@凌驾
公开募捐{
System.out.println(此计数器编号);
}
公共静态void main(字符串[]args)引发InterruptedException{
int number=Integer.parseInt(args[0]);;

对于(int i=1;i)还有其他要求吗?不允许同步线程-这是唯一的条件吗?什么是“不同步”?最终,您将需要某种类型的同步,但分配所要求的可能是不使用
synchronized
关键字。@Steyrix是的,我不允许同步线程,这是唯一的condition@JoseMartinez是的,你是正确的,没有使用
synchronized
关键字更新代码,不需要这样做从用户代码中复制感谢这个解决方案,它工作起来很有魅力:)我想知道当我加入一个不同的for循环时发生了什么?是
run()吗
方法在加入线程之前已经执行?当您在第二个循环中调用join时,线程已经开始并完成了它们的工作。因此我添加了join()的描述方法,您需要在调用start后调用join,以确保它在启动下一个线程后结束。此解决方案似乎有问题。它实际上不是在多线程中完成的…此解决方案一次使用一个线程。我想让线程同时运行会更有趣。感谢您的支持这是一个解决方案,并提供了一种不同的方法来处理可变变量,我一定会对此进行研究。非常感谢:)@PrajwalKrishna欢迎您。但是,您接受了另一个答案,该答案的信息量不如我的,稍后也会发布:(
AtomicInteger number = new AtomicInteger(0);

...

@Override
public void run() {
    System.out.println(number.incrementAndGet());
}
public class CounterThread implements Runnable {
    int counterNumber;

    public CounterThread(int counterNumber) {
        this.counterNumber = counterNumber;
    }

    @Override
    public void run() {
        System.out.println(this.counterNumber);
    }

    public static void main(String[] args) throws InterruptedException {
        int number = Integer.parseInt(args[0]);;
        for (int i = 1; i <= number; i++) {
            CounterThread counterThread = new CounterThread(i);
            Thread thread = new Thread(counterThread);
            thread.start();
            thread.join();
        }
    }
}