Print 1 to 100 using 10 threads in Java
I'm new to multithreading. I got a problem. I used 10 threads in Java to print 1 to 100 below the constraint
>Thread T1 should print:
T2 should print:
same
T10 shall print:
>The final output should be
I tried, but it threw the following exception in all 10 threads:
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)@H_502_31@请让我知道如何解决这个问题.
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); } }@H_502_31@Solution
The simplest way is to have a volatile variable that each thread reads in and updates according to its turn, otherwise it will only wait until its turn When the counter is equal to 100, stop all threads by breaking the external loop
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; } } }@H_502_31@给定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@H_502_31@当然,这是多线程的一个非常糟糕的用法,因为每个线程等待轮到打印并递增计数器.
当线程可以在相对长时间的窗口中独立工作时,多线程工作得很好,然后在需要时可能偶尔会遇到比较或组合它们的结果.
例如,在fork-join模型中,每个线程独立完成其任务,然后合并它们的结果以产生最终结果,例如在合并排序中.但是这假设任务可以很容易地并行化为独立的子任务,这不是这里的情况,因为你的最终输出应该是连续的数字.
所以这里一个简单的循环在很大程度上会更有效,但我可以理解它是出于学习目的.