当前位置: 首页 > 知识库问答 >
问题:

使用java中的10个线程打印1到100

柳涵映
2023-03-14

我是多线程的新手,我有一个问题,要在Java中使用10个线程打印1到100,并使用以下约束。

>

  • 线程 t1 应打印:

    1, 11, 21, 31, ...91

    < code>t2应打印:

    2, 12, 22, 32, ... 92

    同样地

    < code>t10应打印:

    10, 20, 30, ... 100

    最终输出应为:

    1 2 3 ..100

    我已经尝试过了,但它在所有10个线程中都抛出了以下异常

    java.lang.IllegalMonitorStateException
        at java.lang.Object.wait(Native Method)
        at java.lang.Object.wait(Object.java:485)
        at thread.run(MyThread.java:58)
        at java.lang.Thread.run(Unknown Source) 
    

    请让我知道我如何能解决这个问题。

    public class MyThread {
        /**
         * @param args
         */
        public static void main(String[] args) {
            thread.setSequence();
            for(int i = 1; i <= 10; i++) {
                Thread t = new Thread(new thread(i));
                t.setName(i + "");
                t.start();
            }
        }
    }
    
    class thread implements Runnable {
        private static HashMap< String, String> sequence = new HashMap<String, String>();
    
        public static final Object lock = new Object();
        public static String turn = "1"; 
        private int startValue = 0;
        private AtomicInteger counter = new AtomicInteger(1);
    
        public thread(int startValue){
            this.startValue = startValue;
        }
    
        @Override
        public void run() {
            while (!counter.equals(10)){
                synchronized (lock) {
                    if(Thread.currentThread().getName().equals(turn)){  
                        System.out.print(startValue + " ");
                        startValue += 10;
                        counter.incrementAndGet();
                        turn = getNextTurn(turn);
                        try {
                            this.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    else{                       
                        try {
                            this.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    this.notifyAll();
                }
            }
        }
    
        public static void setSequence(){
            for (int i = 1; i <= 10; i++)
                if (i == 10)
                    sequence.put(i + "", 1 + "");
                else
                    sequence.put(i + "", (i + 1) + "");
        }
    
        public static String getNextTurn(String currentTurn){
            return sequence.get(currentTurn);
        }
    }
    
  • 共有3个答案

    姜烨伟
    2023-03-14

    希望这有帮助=)我花了一个小时做这件事。

    package com.xxxx.simpleapp;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class TenThreads {
    
        public int currentTaskValue = 1;
    
        public static void main(String[] args) {
            TenThreads monitor = new TenThreads();
            List<ModThread> list = new ArrayList();
            for (int i = 0; i < 10; i++) {
                ModThread modThread = new ModThread(i, monitor);
                list.add(modThread);
            }
            for (ModThread a : list) {
                a.start();
            }
        }
    
    }
    
    class ModThread extends Thread {
        private int modValue;
        private TenThreads monitor;
    
        public ModThread(int modValue, TenThreads monitor) {
            this.modValue = modValue;
            this.monitor = monitor;
        }
    
        @Override
        public void run() {
            synchronized (monitor) {
                try {
                    while (true) {
                        while (monitor.currentTaskValue % 10 != modValue) {
                            monitor.wait();
                        }
    
                        if (monitor.currentTaskValue == 101) {
                            break;
                        }
                        System.out.println(Thread.currentThread().getName() + " : "
                                + monitor.currentTaskValue + " ,");
                        monitor.currentTaskValue = monitor.currentTaskValue + 1;
                        monitor.notifyAll();
                    }
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }
    

    输出

    Thread-1 : 1 ,
    Thread-2 : 2 ,
    Thread-3 : 3 ,
    Thread-4 : 4 ,
    Thread-5 : 5 ,
    Thread-6 : 6 ,
    Thread-7 : 7 ,
    Thread-8 : 8 ,
    Thread-9 : 9 ,
    ......
    .....
    ...
    Thread-4 : 94 ,
    Thread-5 : 95 ,
    Thread-6 : 96 ,
    Thread-7 : 97 ,
    Thread-8 : 98 ,
    Thread-9 : 99 ,
    Thread-0 : 100 ,
    

    文档故意被遗漏,让你去弄清楚,还有一些小错误!

    郎仰岳
    2023-03-14

    这是当前线程获取锁problem.The的解决方案,我们决定线程是否有资格执行(在此处打印数字)。如果是,请执行操作并通知所有线程他们现在可以尝试。否则等到其他线程通知它。

    public class MyThread extends Thread{
    
    //define the Total No.Of Threads needed
    public static final int TOTAL_THREADS = 10;
    
    public final static Object obj = new Object();
    
    int threadNo;   
    static volatile int counter = 1;
    
    public MyThread(int threadNo){
        this.threadNo= threadNo;
    }
    
    @Override
    public void run(){
    
        //in a synchronized block to acquire lock
        synchronized (obj) {
    
            while(counter<=100){
    
                /*
                 * counter==threadNo => To print the initial numbers till TOTAL_THREADS
                 * counter%TOTAL_THREADS == threadNo => e.g 11%10 = 1 -> 1 will print this, 12%10 = 2 ..
                 * (counter%TOTAL_THREADS == 0) && (TOTAL_THREADS == threadNo) => 10%10 will be 0, 
                 *              and this must be printed by 10 th thread only, ie the highest thread.
                 */
                if(counter == threadNo || (counter%TOTAL_THREADS == threadNo) ||
                        ((counter%TOTAL_THREADS == 0) && (TOTAL_THREADS == threadNo))){
    
                    //Display the output as desired
                    System.out.println(this.threadNo+" printing"+" "+counter++);
    
                    //notify
                    obj.notifyAll();
                }else{
    
                    //current thread not eligible for printing the current counter value, so wait till its notified
                    try {
                        obj.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    
    }
    
    public static void main (String args[]) {
    
        /*
         * Creating as many threads as needed.
         */
        for(int i = 1; i<=TOTAL_THREADS;i++){
            MyThread th = new MyThread(i);
            th.start();
        }
    }
    

    }

    输出将是
    1 打印 1,
    2 打印 2,
    3 打印 3,
    4 打印 4,
    5 打印 5,
    6 打印 6,
    7 打印 7,
    8 打印 8,
    9 打印 9,
    10 打印 10,
    1 打印 11,
    2 打印 12,
    3 打印 13,
    4 打印 14,
    ...
    7 印刷 97,
    8 印刷 98,
    9 印刷 99,
    10 印刷 100

    洪增
    2023-03-14

    最简单的方法是有一个易失性变量,每个线程从中读取并根据其回合进行更新,否则它只是等待到轮到他。当计数器等于100时,您通过中断外循环来停止所有线程运行。

    class MyRunnable implements Runnable {
    
        private static final int LIMIT = 20;
        private static volatile int counter = 0;
        private int id;
    
        public MyRunnable(int id) {
            this.id = id;
        }
    
        @Override
        public void run() {
            outer:
            while(counter < LIMIT) {
                while (counter % NB_THREADS != id) {
                    if(counter == LIMIT) break outer;
                }
                System.out.println("Thread "+Thread.currentThread().getName()+ " printed " + counter);
                counter += 1;
            }
        }
    }
    

    给定20和10个线程的LIMIT,它输出:

    Thread 0 printed 0
    Thread 1 printed 1
    Thread 2 printed 2
    Thread 3 printed 3
    Thread 4 printed 4
    Thread 5 printed 5
    Thread 6 printed 6
    Thread 7 printed 7
    Thread 8 printed 8
    Thread 9 printed 9
    Thread 0 printed 10
    Thread 1 printed 11
    Thread 2 printed 12
    Thread 3 printed 13
    Thread 4 printed 14
    Thread 5 printed 15
    Thread 6 printed 16
    Thread 7 printed 17
    Thread 8 printed 18
    Thread 9 printed 19
    

    当然,这是多线程的一个非常糟糕的用法,因为每个线程都等待轮到它来打印并增加计数器。

    当线程可以在相对长的时间内独立于另一个线程工作时,多线程工作得很好,然后如果需要的话,可以偶尔相遇来比较或组合它们的结果。

    例如,在分叉连接模型中,每个线程独立执行其任务,然后合并其结果以生成最终结果,例如在合并排序中。但这假设任务可以很容易地并行化为独立的子任务,这里的情况并非如此,因为最终输出应该是连续的数字。

    所以这里一个简单的循环会更有效,但是我可以理解这是为了学习。

     类似资料:
    • 我最近开始在Java中使用多线程 我有一个问题,解决了一个问题,我只有5个线程,范围从T1、T2、... T5。 任务是按以下顺序打印从1到10的数字。 我试着用这段代码解决它。 但是由于只允许5个线程,我的解决方案没有被接受,因为我也在< code>for循环的< code>else块中实例化了< code>new Thread。 任何帮助将不胜感激。

    • 问题内容: 我正在尝试使用2个不同的线程交替打印奇数和偶数。我能够使用等待,通知和同步块来实现它,但是现在我想评估是否可以不使用等待,通知和同步来实现它。 以下是我拥有的代码,但无法正常工作: } 有任何想法吗? 根据Bruno的建议,我创建了另一个版本,该版本似乎效果更好: 问题答案: 代码未正确同步,这就是问题所在。 您的代码中允许以下执行顺序: 第一个线程看到,将其设置为并进入块。 第二个线

    • 打印出0。所以,从逻辑上来说,我认为它是强制转换成int的,所以我试着 然后打印出适当的0.1。我不明白为什么第一次它会自动转换成int。它还能在哪里做到这一点?为什么?

    • 问题内容: 使用线程进行奇数打印,创建一个线程类,两个线程实例。 一个将打印奇数,而另一个将打印偶数。 我做了以下编码。但这涉及到死锁状态。有人可以解释一下原因吗? 输出: 奇数1偶数2 然后陷入僵局!!!!!! 谢谢你的帮助。 问题答案: 您正在等待并通知其他对象( 监视器 )。 这个想法是,你在做和做的时候可以打电话等待一个人做。 将您的方法更改为类似 和方法类似。 然后为提供一个对象: 输出

    • 有两个线程,一个是打印偶数,另一个是打印奇数。在下面自定义锁的帮助下,我想按顺序打印数字。问题出在打印一些数字后(显示的数字顺序正确。)线程越来越死机。我花了一个多小时还是找不到问题,对我来说一切都很好。

    • 我需要发送一个pdf文件打印在一个网络应用程序的服务器端,打印机完全支持pdf打印等,它是网络以及服务器。pdf也存储在服务器上。 我尝试的是点击一个按钮,打印出pdf文件,目前我有以下代码: 但我有几个问题,我如何将pdf放入输入流以打印出来,我可以选择诸如双面打印之类的选项,以及如何从JSF web应用程序中调用它 谢谢