Java 多线程程序-线程之间相互切断

Java 多线程程序-线程之间相互切断,java,multithreading,Java,Multithreading,我正在测试一些线程,试图找出如何使用它们。我的问题是,我如何才能让我当前的场景按照我想要的方式工作 我想把这个程序打印出来1-100。我有两种方法奇数和偶数 oddNumbers: public static void oddNumbers() { new Thread(new Runnable() { public void run() { for (int i = 0; i < 100; i++) { if (i % 2 == 1) {

我正在测试一些线程,试图找出如何使用它们。我的问题是,我如何才能让我当前的场景按照我想要的方式工作

我想把这个程序打印出来1-100。我有两种方法<代码>奇数和<代码>偶数

oddNumbers:

public static void oddNumbers() {
  new Thread(new Runnable() {
    public void run() {
      for (int i = 0; i < 100; i++) {
        if (i % 2 == 1) {
          System.out.println(i);
        }
      }
    }
  }).start();
}
public static void evenNumbers() {
  new Thread(new Runnable() {
    public void run() {
      for (int q = 0; q < 100; q++) {
        if (q % 2 == 0) {
          System.out.println(q);
        }
      }
    }
  }).start();
}
public static void main(String[] args) {
  evenNumbers();
  oddNumbers();
}
主要方法

public static void oddNumbers() {
  new Thread(new Runnable() {
    public void run() {
      for (int i = 0; i < 100; i++) {
        if (i % 2 == 1) {
          System.out.println(i);
        }
      }
    }
  }).start();
}
public static void evenNumbers() {
  new Thread(new Runnable() {
    public void run() {
      for (int q = 0; q < 100; q++) {
        if (q % 2 == 0) {
          System.out.println(q);
        }
      }
    }
  }).start();
}
public static void main(String[] args) {
  evenNumbers();
  oddNumbers();
}
因此,据我所知,方法
oddNumbers
evenNumbers
在不同的线程上运行。如果是,为什么我的输出不是1-100

以下是我得到的输出:

0
2
4
6
.
.
.
50
1
3
5
.
.
.
99
52
54
56
.
.
.
100
大约在
evenNumbers
循环的一半时,
oddNumbers
循环将其切断。为什么会发生这种情况,我如何设置它以便打印1-100


提前谢谢

我知道你不想让它们交替,只要理解为什么每一个都要执行这么长时间

该决定由操作系统的调度程序做出。它决定何时切换到另一个线程。您的示例中的问题是,您的线程非常小,执行速度非常快

调度程序给线程一段时间的执行权,问题是,这段时间足以显示循环中的许多数字,因此它们不会被切换很多次


如果你让它运行更长的时间,使用更大的数字,你会得到更好的结果。或者,你也可以让循环在打印之前花费更长的时间,添加一些需要时间的微积分,这样它就不会在一行中打印那么多的数字

我知道你不想让它们交替,只要理解为什么每一个都要执行这么长时间

该决定由操作系统的调度程序做出。它决定何时切换到另一个线程。您的示例中的问题是,您的线程非常小,执行速度非常快

调度程序给线程一段时间的执行权,问题是,这段时间足以显示循环中的许多数字,因此它们不会被切换很多次


如果你让它运行更长的时间,使用更大的数字,你会得到更好的结果。或者,你也可以让循环在打印之前花费更长的时间,添加一些需要时间的微积分,这样它就不会在一行中打印那么多的数字

因为您没有告诉线程等待剩余的参与者

很难说下一个线程是否在启动后继续工作,或者启动需要多长时间。它可能是几个cpu周期或2秒

您想要实时关键应用程序的精确指令定时吗?开始fpga编程

对于这个java pc程序,您可以使用循环屏障,让它们一起执行步骤,而不需要任何启动优先级

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public class Demo {
    public static CyclicBarrier barrier = new CyclicBarrier(2);
    public static void oddNumbers() {
          new Thread(new Runnable() {
            public void run() {
              for (int i = 0; i < 100; i++) {
                  try {
                    barrier.await();
                } catch (InterruptedException | BrokenBarrierException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                if (i % 2 == 1) {
                  System.out.println(i);
                }
              }
            }
          }).start();
        }


        public static void evenNumbers() {
          new Thread(new Runnable() {
            public void run() {
              for (int q = 0; q < 100; q++) {
                  try {
                    barrier.await();
                } catch (InterruptedException | BrokenBarrierException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                if (q % 2 == 0) {
                  System.out.println(q);
                }
              }
            }
          }).start();
        }


        public static void main(String[] args) {
          evenNumbers();
          oddNumbers();
        }
}
而不是

0
1
2
3
在打印到控制台之前,可以使用第三个操作合并两个线程的结果来解决这个问题


这里的难点是在多线程环境中请求串行操作。

因为您没有告诉线程等待剩余的参与者

很难说下一个线程是否在启动后继续工作,或者启动需要多长时间。它可能是几个cpu周期或2秒

您想要实时关键应用程序的精确指令定时吗?开始fpga编程

对于这个java pc程序,您可以使用循环屏障,让它们一起执行步骤,而不需要任何启动优先级

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public class Demo {
    public static CyclicBarrier barrier = new CyclicBarrier(2);
    public static void oddNumbers() {
          new Thread(new Runnable() {
            public void run() {
              for (int i = 0; i < 100; i++) {
                  try {
                    barrier.await();
                } catch (InterruptedException | BrokenBarrierException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                if (i % 2 == 1) {
                  System.out.println(i);
                }
              }
            }
          }).start();
        }


        public static void evenNumbers() {
          new Thread(new Runnable() {
            public void run() {
              for (int q = 0; q < 100; q++) {
                  try {
                    barrier.await();
                } catch (InterruptedException | BrokenBarrierException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                if (q % 2 == 0) {
                  System.out.println(q);
                }
              }
            }
          }).start();
        }


        public static void main(String[] args) {
          evenNumbers();
          oddNumbers();
        }
}
而不是

0
1
2
3
在打印到控制台之前,可以使用第三个操作合并两个线程的结果来解决这个问题


这里的难点是在多线程环境中请求串行操作。

好的,在奇数线程之前启动偶数线程。。。但是,即使它们同时启动,为什么您认为它们会交替呢?与程序的实际执行时间相比,您的输出缓冲区更可能填满并刷新到输出。加上时间戳,你可能会看到更多的重叠。这让我想起:“一个程序员遇到了一个问题。他心想,“我知道,我会用线程解决它的!”。现在有问题了。你说的“同一时间”是什么意思?线程可能同时在多核上运行,但System.out.print有一个可序列化的同步块writes@Kaelinator好吧,就像我说的,你先启动一个线程,这样它就可以在另一个线程启动之前通过它的编号;然后另一个开始并“切断”第一个线程。好的,你先开始偶数线程,然后再开始奇数线程。。。但是,即使它们同时启动,为什么您认为它们会交替呢?与程序的实际执行时间相比,您的输出缓冲区更可能填满并刷新到输出。加上时间戳,你可能会看到更多的重叠。这让我想起:“一个程序员遇到了一个问题。他心想,“我知道,我会用线程解决它的!”。现在有问题了。你说的“同一时间”是什么意思?线程可能同时在多核上运行,但System.out.print有一个可序列化的同步块writes@Kaelinator好吧,就像我说的,你先启动一个线程,这样它就可以在另一个线程启动之前通过它的编号;然后另一个开始并“切断”第一条线。