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

在java中使用10个线程打印1到100,java,multithreading,Java,Multithreading,我是多线程新手,我有一个问题要在Java中使用10个线程打印1到100个线程,并带有以下约束 线程t1应打印: 1、11、21、31。。。91 t2应打印: 2、12、22、32。。。92 同样地 t10应打印: 10、20、30。。。一百 最终输出应该是 1 2 3。。一百 我已经尝试过了,但它在所有10个线程中都抛出了以下异常: java.lang.IllegalMonitorStateException at java.lang.Object.wait(Native Metho

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

  • 线程
    t1
    应打印:

    1、11、21、31。。。91

    t2
    应打印:

    2、12、22、32。。。92

    同样地

    t10
    应打印:

    10、20、30。。。一百

  • 最终输出应该是

    1 2 3。。一百

  • 我已经尝试过了,但它在所有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);
        }
    }
    
    公共类读取{
    /**
    *@param args
    */
    公共静态void main(字符串[]args){
    thread.setSequence();
    for(int i=1;i sequence=new HashMap();
    公共静态最终对象锁=新对象();
    公共静态字符串turn=“1”;
    私有int startValue=0;
    私有AtomicInteger计数器=新的AtomicInteger(1);
    公共线程(int startValue){
    this.startValue=startValue;
    }
    @凌驾
    公开募捐{
    而(!counter.equals(10)){
    已同步(锁定){
    如果(Thread.currentThread().getName().equals(turn)){
    系统输出打印(startValue+“”);
    起始值+=10;
    counter.incrementAndGet();
    turn=getNextTurn(turn);
    试一试{
    这个。等等();
    }捕捉(中断异常e){
    e、 printStackTrace();
    }
    }
    否则{
    试一试{
    这个。等等();
    }捕捉(中断异常e){
    e、 printStackTrace();
    }
    }
    this.notifyAll();
    }
    }
    }
    公共静态void setSequence(){
    
    对于(inti=1;i来说,最简单的方法是为所有这些对象保留公共资源。 持有一个列表,每个线程都会插入到列表中,最后你可以排序和打印。。 如果你想让他们在你的订单上做这件事,这将不是很有效,因为你不需要10个线程来做这件事

    这样会更快,并且会使用10个线程来完成一些工作,但是当每个人都完成时,您仍然需要做一些工作

    公共类PrintNumbersbyThreads实现Runnable{
    
    public class PrintNumbersbyThreads implements Runnable {
        private int i;
    
        public PrintNumbersbyThreads(int i) {
            this.i = i;
        }
    
        public static void main(String[] args) {
            PrintNumbersbyThreads p = new PrintNumbersbyThreads(1);
            PrintNumbersbyThreads p2 = new PrintNumbersbyThreads(2);
            PrintNumbersbyThreads p3 = new PrintNumbersbyThreads(3);
            Thread t1 = new Thread(p, "t1");
            Thread t2 = new Thread(p2, "t2");
            Thread t3 = new Thread(p3, "t3");
            t1.start();
    
            try {
                t1.join();
                t2.start();
                t2.join();
                t3.start();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    
        @Override
        public void run() {
            System.out.println("\n" + Thread.currentThread().getName() + " prints  ");
            for (int j = 0; j < 10; j++) {
                System.out.print(i + " ");
                i = i + 10;
            }
        }
    }
    
    私人互联网i; 公共PrintNumbersbyThreads(int i){ 这个。i=i; } 公共静态void main(字符串[]args){ PrintNumbersbyThreads p=新的PrintNumbersbyThreads(1); PrintNumbersbyThreads p2=新的PrintNumbersbyThreads(2); PrintNumbersbyThreads p3=新的PrintNumbersbyThreads(3); 螺纹t1=新螺纹(p,“t1”); 螺纹t2=新螺纹(p2,“t2”); 螺纹t3=新螺纹(p3,“t3”); t1.start(); 试一试{ t1.join(); t2.start(); t2.连接(); t3.start(); }捕捉(中断异常e){ e、 printStackTrace(); } } @凌驾 公开募捐{ System.out.println(“\n”+线程.currentThread().getName()+打印”); 对于(int j=0;j<10;j++){ 系统输出打印(i+“”); i=i+10; } } }
    编写了3个线程的示例代码,输出为

    t1
    打印:

    11121314161718191

    t2
    打印:

    2 12 22 32 42 52 62 82 92

    t3
    打印:

    3132333435363738393


    希望这就是您正在寻找的吗?

    最简单的方法是使用一个可变变量,每个线程从中读入并根据其轮次进行更新,否则它只会等待轮到自己。当
    计数器等于
    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;
            }
        }
    }
    
    当然,这是多线程的一个非常糟糕的用法,因为每个线程都会等待轮到它打印并递增计数器

    当线程可以在相对较长的时间内独立于另一个线程工作时,多线程就可以很好地工作,如果需要的话,还可以偶尔碰头比较或合并它们的结果

    例如,在fork-join模型中,每个线程独立地执行其任务,然后合并它们的结果以生成最终结果,例如在合并排序中。但这假设任务可以轻松地并行到独立的子任务中,这里不是这种情况,因为您的最终输出应该是连续的数字


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

    错误是由于调用
    wait
    而不是在正确的对象上引发的。
    wait()
    应该在获取锁的对象上调用,该对象由
    synchronized
    关键字暗示。

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

    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();
                }
            }
        }
    }
    

    为了让您弄清楚,特意省略了文档,还有一些小错误!

    我已经编写了一个通用代码,它将记录您要打印的位置和要使用的线程数

    public class ThreadedPrinting {
        private Object locks[];
    
        private static class Printer extends Thread {
            int curVal;
            int endVal;
            Object myLock;
            Object nextLock;
            int step;
    
            public Printer(int startFrom, int endVal, int step, Object myLock, Object nextLock){
                this.curVal = startFrom;
                this.endVal = endVal;
                this.step = step;
                this.myLock = myLock;
                this.nextLock = nextLock;
                this.step = step;
            }
    
            @Override
            public void run(){
                synchronized(myLock) {
                    while (curVal <= endVal) {
                        try {
                            myLock.wait();
                            System.out.println(curVal);
                            curVal += step;
                        }
                        catch(InterruptedException e) {}
                        synchronized(nextLock) {
                            nextLock.notify();
                        }
                    }
                }
                synchronized(nextLock) {
                    nextLock.notify(); /// this ensures all worker threads exiting at the end
                }
            }
        } // Printer
    
        public ThreadedPrinting(int maxNum, int threads) {
            locks = new Object[threads];
            int i;
            for(i = 0; i < threads; ++i) locks[i] = new Object();
            for(i = 0; i < threads -1 ; ++i) {
                Printer curPrinter = new Printer(i, maxNum, threads, locks[i], locks[i+1]);
                curPrinter.start();
            }
            Printer lastPrinter = new Printer(i, maxNum, threads, locks[threads - 1], locks[0]);
            lastPrinter.start();
        }
    
        public void start() {
            synchronized (locks[0]) {
                locks[0].notify();
            }
        }
    
        public static void main(String[] args) {
            ThreadedPrinting printer = new ThreadedPrinting(1000,7);
            printer.start();
        }
    }
    
    公共类线程打印{
    私有对象锁[];
    私有静态类打印机扩展线程{
    int曲线;
    内端点;
    对象myLock;
    对象nextLock;
    整数步;
    公用打印机(int startFrom、int endVal、int step、对象myLock、对象nextLock){
    this.curVal=startFrom;
    this.endVal=endVal;
    这个步骤=步骤;
    this.myLock=myLock;
    this.nextLock=nextLock;
    这个步骤=步骤;
    }
    @凌驾
    公开募捐{
    已同步(myLock){
    
    虽然(curVal嗯,我没有代码…但是透视图似乎是 有100项任务需要完成
    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 ,
    
    public class ThreadedPrinting {
        private Object locks[];
    
        private static class Printer extends Thread {
            int curVal;
            int endVal;
            Object myLock;
            Object nextLock;
            int step;
    
            public Printer(int startFrom, int endVal, int step, Object myLock, Object nextLock){
                this.curVal = startFrom;
                this.endVal = endVal;
                this.step = step;
                this.myLock = myLock;
                this.nextLock = nextLock;
                this.step = step;
            }
    
            @Override
            public void run(){
                synchronized(myLock) {
                    while (curVal <= endVal) {
                        try {
                            myLock.wait();
                            System.out.println(curVal);
                            curVal += step;
                        }
                        catch(InterruptedException e) {}
                        synchronized(nextLock) {
                            nextLock.notify();
                        }
                    }
                }
                synchronized(nextLock) {
                    nextLock.notify(); /// this ensures all worker threads exiting at the end
                }
            }
        } // Printer
    
        public ThreadedPrinting(int maxNum, int threads) {
            locks = new Object[threads];
            int i;
            for(i = 0; i < threads; ++i) locks[i] = new Object();
            for(i = 0; i < threads -1 ; ++i) {
                Printer curPrinter = new Printer(i, maxNum, threads, locks[i], locks[i+1]);
                curPrinter.start();
            }
            Printer lastPrinter = new Printer(i, maxNum, threads, locks[threads - 1], locks[0]);
            lastPrinter.start();
        }
    
        public void start() {
            synchronized (locks[0]) {
                locks[0].notify();
            }
        }
    
        public static void main(String[] args) {
            ThreadedPrinting printer = new ThreadedPrinting(1000,7);
            printer.start();
        }
    }
    
    public class BigSequence {
        public static void main(String[] args) {
            BigPrintNum p = new BigPrintNum();
            int max = 20;
            int no_threads = 11;
            for(int i=0;i<no_threads;i++){
                boolean b[] = new boolean[no_threads];
                b[i] = true;
                Thread t = new Thread(new BigPrint(p, max, b,no_threads));
                t.start();
            }
        }
    }
    class BigPrint implements Runnable {
    
        int num=0;
        BigPrintNum p;
        int max;
        int no_threads;
        boolean b[];
        public BigPrint(BigPrintNum p,int max,boolean b[],int no_threads){
            this.p = p;
            this.max = max;
            this.b = b;
            this.no_threads = no_threads;
        }
        @Override
        public void run() {
            int n = 0;
            for(int i=0;i<no_threads;i++){
                if(b[i] == true){
                    n = i;
                    num = i;
                }
            }
            while(num<=max){
                p.print(num, n, no_threads);
                num += no_threads;
            }
        }   
    }
    class BigPrintNum {
        int turn = 0;
        public synchronized void print(int n,int i,int no_threads){
            while(this.turn != i){
                try{
                    wait();
                }catch(InterruptedException e){
                    e.printStackTrace();
                }
            }
            System.out.println(i + "th seq = " + n);
            this.turn = (i+1)%no_threads;
            notifyAll();
        }
    }
    
    public class ThreadSequence 
    {
    
        public static int totalThread;
        public static void main(String[] args) 
        {
    
            MyLock myLock = new MyLock();
            totalThread = 10;
    
            for(int i=1;i<=totalThread;i++)
            {
                MyThread myThread = new MyThread(i,myLock);
                myThread.start();
            }
    
        }
    
    }
    
    class MyLock
    {
    
        public int counter = 0;
    
    }
    
    class MyThread extends Thread{
    
        public MyLock lock;
        public int no;
        public MyThread(int no,MyLock lock)
        {
            super("My Thread No "+no);
            this.no = no;
            this.lock = lock;
        }
    
        public void run()
        {
    
            synchronized (lock) 
            {
    
                while(true)
                {
    
                    while(lock.counter%ThreadSequence.totalThread !=(this.no-1))
                    {
    
                        try 
                        {
    
                            if(lock.counter > 99)
                            {
                                break;
                            }
    
                            lock.wait();
    
                        } catch (InterruptedException e) 
                        {
                            e.printStackTrace();
                        }
                    }
                    if(lock.counter > 99)
                    {
                        break;
                    }
    
                    System.out.println("Current Thread "+Thread.currentThread().currentThread()+" --- Current Count "+(lock.counter+1));
                    lock.counter = lock.counter +1 ;
                    lock.notifyAll();   
                }
            }
    
        }
    }
    
    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();
        }
    }
    
     private final int index;
     private final AtomicInteger atomicInteger;
     private final CyclicBarrier cyclicBarrier;
    
    
    public class PrintSequence {
    
    
        public static void main(String[] args) {
            ExecutorService executorService = Executors.newFixedThreadPool(10);
            final AtomicInteger atomicInteger = new AtomicInteger(1);
            final CyclicBarrier cyclicBarrier = new CyclicBarrier(10, ()-> {
                System.out.println("a cycle done");
            });
    
            IntStream.rangeClosed(0, 9)
                    .boxed()
                    .map(i -> new PrintSequenceTask(i, atomicInteger, cyclicBarrier))
                    .map(p -> executorService.submit(p))
                    .collect(Collectors.toList());
    
            executorService.shutdown();
    
        }
    }
    
    
    class PrintSequenceTask implements Runnable {
        private final int index;
        private final AtomicInteger atomicInteger;
        private final CyclicBarrier cyclicBarrier;
    
        PrintSequenceTask(int index, AtomicInteger atomicInteger, CyclicBarrier cyclicBarrier) {
            this.index = index;
            this.atomicInteger = atomicInteger;
            this.cyclicBarrier = cyclicBarrier;
        }
    
        @Override
        public void run(){
            for(int i=1; i<10;i++){
                while (((atomicInteger.get()-index-1)%10 != 0)){}
                System.out.println(Thread.currentThread().getName()+" "+(atomicInteger.get()));
                atomicInteger.getAndIncrement();
                await();
            }
        }
    
        public void await(){
            try {
                cyclicBarrier.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (BrokenBarrierException e) {
                e.printStackTrace();
            }
        }
    }