Java 使用7个线程生成无限数字序列
我试图在Java中使用不同的线程生成无限的数字序列。 这是我的密码:Java 使用7个线程生成无限数字序列,java,multithreading,concurrency,Java,Multithreading,Concurrency,我试图在Java中使用不同的线程生成无限的数字序列。 这是我的密码: import java.util.*; public class infinite_Streams { volatile boolean keepGenerating = true; volatile ArrayList<Integer> s1 = new ArrayList<>(); Object lock1 = new Object(); Random random
import java.util.*;
public class infinite_Streams {
volatile boolean keepGenerating = true;
volatile ArrayList<Integer> s1 = new ArrayList<>();
Object lock1 = new Object();
Random random = new Random();
ArrayList<Object> obj1 = new ArrayList<>();
void generateInfiniteStream() {
synchronized (lock1) {
//BLOCK 1
while(keepGenerating) {
Object temp = Thread.currentThread().getId();
System.out.println("Thread is : " + temp);
s1.add(random.nextInt(11));
}
}
//BLOCK 1 ENDS
//BLOCK 2
// for (int i = 0; i < 100000; i++) {
// Object temp = Thread.currentThread().getId();
// System.out.println("Thread is : " + temp);
// s1.add(random.nextInt(11));
// }
//BLOCK 2 ENDS
}
void generateThreads(int num_threads){
Thread[] threads = new Thread[num_threads];
for(int i = 0 ; i < num_threads ; i++){
threads[i] = new Thread(new Runnable() {
@Override
public void run() {
generateInfiniteStream();
}
});
}
for (Thread thread : threads) {
thread.start();
}
try{
for (Thread thread : threads) {
thread.join();
}
}catch (InterruptedException e){
e.printStackTrace();
}
}
public void shutdown(){
keepGenerating = false;
}
public static void main(String [] args){
List<Integer> l1 = new ArrayList<>();
int num_threads = 7;
Scanner scan1 = new Scanner(System.in);
infinite_Streams is1 = new infinite_Streams();
is1.generateThreads(num_threads);
System.out.println("Press any key to interrupt");
Scanner scan2 = new Scanner(System.in);
scan2.nextLine();
is1.shutdown();
}
}
问题是我只看到一个特定的线程,比如说12
,所以输出看起来像线程总是:12
。
另一方面,如果我对\\BLOCK1
代码进行注释,而运行\\BLOCK2
代码(生成有限数量的数字),我会在输出中看到不同的线程编号,正如预期的那样。喜欢
线程为:12
线程为:12
线程为:14
等
有人能解释一下,为什么我在生成无穷多个线程时没有看到不同的线程数?其中一个线程获得了锁。然后,它将在(keepGenerating)期间执行,直到您更改此变量为止。所有其他线程都在等待,直到锁释放。将keepGenerating设置为false时,运行的线程完成循环。另一个线程获得锁。但此时keepGenerating已经为false,所以它不执行这个循环,只退出。然后,下一个线程获得锁,并再次看到无需执行任何操作。等等 所以实际上只有一个线程在生成随机数 如果希望每个线程生成随机数,则应在同步块之外而不是同步块内使用while(keepGenerating),如下所示:
while(keepGenerating) {
synchronized (lock1) {
Object temp = Thread.currentThread().getId();
System.out.println("Thread is : " + temp);
s1.add(random.nextInt(11));
}
}
然后,每个线程将不会永远获得锁,而只是为了生成数字和输出的一次执行。然后锁将被释放,其他线程可以获得它,以此类推。其中一个线程获得锁。然后,它将在(keepGenerating)期间执行,直到您更改此变量为止。所有其他线程都在等待,直到锁释放。将keepGenerating设置为false时,运行的线程完成循环。另一个线程获得锁。但此时keepGenerating已经为false,所以它不执行这个循环,只退出。然后,下一个线程获得锁,并再次看到无需执行任何操作。等等 所以实际上只有一个线程在生成随机数 如果希望每个线程生成随机数,则应在同步块之外而不是同步块内使用while(keepGenerating),如下所示:
while(keepGenerating) {
synchronized (lock1) {
Object temp = Thread.currentThread().getId();
System.out.println("Thread is : " + temp);
s1.add(random.nextInt(11));
}
}
然后,每个线程将不会永远获得锁,而只是为了生成数字和输出的一次执行。然后锁将被释放,其他线程可以获得它,等等。您的第二个块也同步了吗?我的猜测是,
keepGenerating
设置为false之后,任何其他线程都会因为您的synchronized(lock1)
而获得锁。如果希望代码在没有synchronized
的情况下工作,请删除ArrayList
上的“volatile”,使用ConcurrentDeque
,每个线程使用Random
(Random
类不是线程安全的)。至于关机,您可以尝试使用Thread.interrupt()
@nodata发现我的错误。是块2
也是同步的。我添加了keepGenerating
以通过键盘中断终止线程。但代码的行为与以前相同,我只是使用true
代替keepGenerating
。您的第二个块也同步了吗?我的猜测是,keepGenerating
设置为false之后,任何其他线程都会因为您的synchronized(lock1)
而获得锁。如果希望代码在没有synchronized
的情况下工作,请删除ArrayList
上的“volatile”,使用ConcurrentDeque
,每个线程使用Random
(Random
类不是线程安全的)。至于关机,您可以尝试使用Thread.interrupt()
@nodata发现我的错误。是块2
也是同步的。我添加了keepGenerating
,以通过键盘中断终止线程。但代码的行为与以前相同,当时我只是使用true
代替keepGenerating
。