使用多个线程按顺序打印语句 [英] Using multiple threads to print statements sequentially

查看:91
本文介绍了使用多个线程按顺序打印语句的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用三个线程打印1到10之间的数字。线程1打印1,2打印2,3打印3,4再次由线程1打印,依此类推。

I am trying to print numbers from 1 to 10 using three threads. thread 1 prints 1, 2 prints 2, 3 prints 3, 4 is printed by thread 1 again and so on.

我创建了一个共享打印机资源,可以帮助这些线程打印号码。但我感到很困惑,因为我怎么能让所有线程都能看到这个数字。

I have created a shared printer resource that helps those threads to print number. But I am getting confused as how can i make the number to be visible by all threads.

问题是每个线程都看到了他们自己的数字副本,而我需要相同的所有线程共享的数字。

The problem is eachthread is seeing their own copy of number while I need the same number to be shared by all threads.

我正在尝试创建此示例以用于学习目的。我在SO上看到过其他类似问题的页面,但我无法理解这个问题。

I am trying to create this example for learning purposes. I have seen other pages on SO that had same kind of problem but I am not able to get the concept.

感谢任何帮助。

这个例子与我的做法有何不同?
使用Java中的两个线程打印偶数和奇数

how is this example diffrent from what I am doing? Printing Even and Odd using two Threads in Java

public class PrintAlternateNumber {


    public static void main(String args[]) {

        SharedPrinter printer = new SharedPrinter();

        Thread t1 = new Thread(new myRunnable2(printer,10,1),"1");
        Thread t2 = new Thread(new myRunnable2(printer,10,2),"2");
        Thread t3 = new Thread(new myRunnable2(printer,10,3),"3");

        t1.start();
        t2.start();
        t3.start();     
    }
}

class myRunnable2 implements Runnable {

    int max;
    SharedPrinter printer;
    int threadNumber;

    int number=1;

    myRunnable2(SharedPrinter printer,int max,int threadNumber) {
        this.max=max;
        this.printer=printer;
        this.threadNumber=threadNumber;
    }

    @Override
    public void run() {
        System.out.println(" The thread that just entered run "+ Thread.currentThread().getName());     
        for(int i =1;i<max;i++){
            try {
                printer.print(i,threadNumber);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }


}


class SharedPrinter {

    boolean canPrintFlag=false;


    public synchronized void print(int number,int threadNumber) throws InterruptedException{

        if(number%3==threadNumber) {
            canPrintFlag=true;
        }

        while(!canPrintFlag)
        {
            System.out.println(Thread.currentThread().getName() + " is waiting as it cannot print " + number);
            wait();


        }
        System.out.println(Thread.currentThread().getName()+" printed "+number);
        canPrintFlag=false;
        notifyAll();



    }
}

//output
 //The thread that just entered run 2
// The thread that just entered run 3
 //The thread that just entered run 1
//3 is waiting as it cannot print 1
//1 printed 1
//1 is waiting as it cannot print 2
//3 is waiting as it cannot print 1
//2 is waiting as it cannot print 1



技术第二



它仍然不完整但我很接近

Technique second

it is still incomplete but I am close

输出

0印刷品0
2印刷品2
1印刷品1

0printed by0 2printed by2 1printed by1

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

class AlternateNumber {

    public static void main(String args[]) {

        printerHell ph = new printerHell();
        BlockingQueue<Integer> queue = new ArrayBlockingQueue<Integer>(10);     
        for(int i=0;i<10;i++)
        {
            queue.add(i);
        }

        Thread t1 = new Thread(new myRunnableHell(queue,0,ph),"0");
        Thread t2 = new Thread(new myRunnableHell(queue,1,ph),"1");
        Thread t3 = new Thread(new myRunnableHell(queue,2,ph),"2");

        t1.start();
        t2.start();
        t3.start();     
    }

}

class myRunnableHell implements Runnable {

    BlockingQueue<Integer> queue;   
    int threadNumber;
    printerHell ph;

    myRunnableHell(BlockingQueue<Integer> queue, int threadNumber,printerHell ph) {

        this.queue=queue;       
        this.threadNumber=threadNumber;
        this.ph=ph;
    };

    int currentNumber;

    @Override
    public void run() {

        for(int i=0;i<queue.size();i++)
        {
            currentNumber=queue.remove();

            if(threadNumber%3==currentNumber) 
            {
                ph.print(currentNumber);
            }   

        }   

    }   

}

class printerHell {

    public synchronized void print(int Number)
    {
        System.out.println(Number + "printed by" + Thread.currentThread().getName());
    }


}


推荐答案

请在此处查看我的解决方案..

Please see my solution here..

使用简单的等待/通知
https://stackoverflow.com/a/31668619/1044396

Using simple wait/notify https://stackoverflow.com/a/31668619/1044396

使用循环障碍:
https://stackoverflow.com/a/23752952/1044396

对于'与偶数/奇数线程问题的不同之处'的查询。
- >它几乎相同......而不是维持两个状态还有一个状态来调用第三个线程,所以我相信,这可以扩展任意数量的线程。

For your query on 'How different it is from even/odd thread problem. --> it is almost same ... instead of maintaining two states have one more state to call the third thread, so I believe,this can be extended any number of threads.

编辑:

当你想要'n'个线程来顺序完成工作时,你可以查看这种方法。(而不是不同的类别t1,t2,t3等)

You may view this approach when you want to have 'n' number of threads to do the work sequentially.(Instead of having different classes t1,t2,t3 etc)

https:// codereview.stackexchange.com/a/98305/78940

EDIT2:
再次在此处复制代码以获取上述解决方案

Copying the code here again for the above solution

我尝试使用单个类'Thrd'来解决,它使用其起始编号初始化。

I tried to solve using a single class 'Thrd' which gets initialized with its starting number.

ThreadConfig类,其大小为你想要创建的线程总数。

ThreadConfig class which as size of total number of threads you want to create.

保持上一个线程状态的状态类。(维持排序)

State class which maintains the state of the previous thread.(to maintain ordering)

在这里你去..(请回顾并告诉我你的看法)

Here you go..(please review and let me know your views)

编辑:
Ho它有效 - >

How it works -->

当一个线程Tx有机会执行时......它将用x设置状态变量的状态。所以下一个线程(Tx + 1)等待,一旦状态得到更新就会有机会。这样你就可以保持线程的顺序。

when a thread Tx gets a chance to execute.. it will set state variable's state with x. So a next thread(Tx+1) waiting , will get a chance once state gets updated. This way you can maintain the ordering of threads.

我希望我能够解释代码。请运行它并查看或告诉我有关以下代码的任何特定查询

I hope i am able to explain the code. Please run it and see or let me know for any specific queries on the below code

1)
package com.kalyan.concurrency;

1) package com.kalyan.concurrency;

    public class ThreadConfig {

        public static final int size = 5;

    }

2)package com.kalyan.concurrency;

2) package com.kalyan.concurrency;

    public class State {

      private volatile int state ;

        public State() {
            this.state =3;
        }

        public State(int state) {
            this.state = state;
        }

        public  int getState() {
            return state;
        }

        public  void setState(int state) {
            this.state = state;
        }


    }

3)包裹com.kalyan.concurrency;

3) package com.kalyan.concurrency;

        public class Thrd implements Runnable {

            int i ;
            int name;
            int prevThread;
            State s;
            public Thrd(int i,State s) {
                this.i=i;
                this.name=i;
                this.prevThread=i-1;
                if(prevThread == 0) prevThread=ThreadConfig.size;
                this.s=s;
            }

            @Override
            public void run() {


                while(i<50)
                {
                    synchronized(s)
                      {
                          while(s.getState() != prevThread)
                          {


                                  try {
                                    s.wait();
                                } catch (InterruptedException e) {
                                    // TODO Auto-generated catch block
                                    e.printStackTrace();
                                }
                              }

                          } 

                              synchronized(s)
                              {
                               //if(s.getState() ==3)

                              if(s.getState()==prevThread)
                               System.out.println("t"+ name+ i);
                               s.setState(name);
                                   i = i +ThreadConfig.size ;
                              s.notifyAll();


                             }   
                }

            }

        }

4)
包com.kalyan.concurrency;

4) package com.kalyan.concurrency;

        public class T1t2t3 {
        public static void main(String[] args) {

            State s = new State(ThreadConfig.size);


            for(int i=1;i<=ThreadConfig.size;i++)
            {
                Thread T = new Thread(new Thrd(i,s));   
                T.start();

            }



        }
        }

输出:

 t11
 t22
 t33
 t44
 t55
 t16
 t27
 t38
 t49
 t510
 t111
 t212
 t313
 t414
 t515
 t116..............

这篇关于使用多个线程按顺序打印语句的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆