Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/390.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 使用7个线程生成无限数字序列_Java_Multithreading_Concurrency - Fatal编程技术网

Java 使用7个线程生成无限数字序列

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

我试图在Java中使用不同的线程生成无限的数字序列。 这是我的密码:

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