为了账号安全,请及时绑定邮箱和手机立即绑定

如何使用多线程打印序列中的数字

如何使用多线程打印序列中的数字

智慧大石 2023-07-19 17:04:42
我想用 T1-1、T2-2、T3-3、T1-4、T2-5、T3-6 等线程按顺序打印数字public class NumberGame {    static int a=1;    public static void main(String args[]) throws InterruptedException    {        PrintSequenceRunnable C1=new PrintSequenceRunnable("T1",a);        PrintSequenceRunnable C2=new PrintSequenceRunnable("T2",a);        PrintSequenceRunnable C3=new PrintSequenceRunnable("T3",a);        Thread t1 = new Thread(C1);        Thread t2 = new Thread(C2);        Thread t3 = new Thread(C3);        t1.start();        t2.start();        t3.start();     }}public class PrintSequenceRunnable implements Runnable {    String tname;    int a;    PrintSequenceRunnable(String tname, int a )    {        this.tname = tname;        this.a = a;    }    @Override    public void run() {        synchronized (this) {            for(int i=0; i<10;i++)            {                System.out.println(tname+" "+a);                a++;                try {                    this.wait(1000);                    this.notify();                } catch (InterruptedException e) {                    // TODO Auto-generated catch block                    e.printStackTrace();                }            }        }        // TODO Auto-generated method stub    }}但我的输出就像T1-1 T2-1 T3-1 T1-2 T3-2 T2-2 T3-3 T1-3 T2-3 T3-4 T1-4 T2-4 T3-5 T1-5 T2-5 T3-6 T1- 6 T2-6 T1-7 T2-7 T3-7 T2-8 T3-8 T1-8 T2-9 T3-9 T1-9 T2-10 T1-10 T3-10谁能帮我。
查看完整描述

2 回答

?
慕田峪7331174

TA贡献1828条经验 获得超13个赞

问题是:

  1. 该设计存在线程之间引发条件的问题,您需要同步它们。

  2. 在使用构造函数时,PrintSequenceRunnable(String tname, int a )您将发送原始变量的副本a,它是静态成员NumberGame。所以,每个PrintSequenceRunnable都有自己的变量a

我的建议是使用方法wait和同步每个线程notify。我拿了你的代码并做了一些修改:

数字游戏

public class NumberGame {


    public static void main(String args[]) throws InterruptedException

    {       

        PrintSequenceRunnable C1=new PrintSequenceRunnable("T1");

        PrintSequenceRunnable C2=new PrintSequenceRunnable("T2");

        PrintSequenceRunnable C3=new PrintSequenceRunnable("T3");


        Thread t1 = new Thread(C1);

        Thread t2 = new Thread(C2);

        Thread t3 = new Thread(C3);


        t1.start();

        t2.start();

        t3.start();


        Thread.sleep(1);//Wait 1 ms to avoid a raise condition


        PrintSequenceRunnable.activateNextItem(); //Start sequence.



        t1.join();

        t2.join();

        t3.join();


        System.out.println("--END--");

    }

}

打印序列可运行


import java.util.Vector;


public class PrintSequenceRunnable implements Runnable {    


    static private int a = 0;

    private static Vector<PrintSequenceRunnable> items = new Vector<PrintSequenceRunnable>();


    /**

     * Method to select the next Thread which will be activate to continue its thread.

     */

    public static synchronized void activateNextItem() {

        int index = a % items.size();

        items.get(index).activate();

    }


    private String tname;

    private Object sempahoro = new Object(); //Object to sinchrony the  thread


    public PrintSequenceRunnable(String tname)

    {

        this.tname = tname;

        items.add(this);

    }


    public void activate()

    {

        synchronized (sempahoro) {

            sempahoro.notify();

        }

    }


    @Override

    public void run() {

        for(int i=0; i<10;i++)

        {


            synchronized (sempahoro) {

                try {

                    sempahoro.wait();

                } catch (InterruptedException e) {

                    e.printStackTrace();

                }

            }


            a++;

            System.out.println(tname+" "+a);            

            activateNextItem(); //Raise the next thread.

        }

        // TODO Auto-generated method stub

    }

}

在此示例中,方法activateNextItem, fromPrintSequenceRunnable` 将决定通知哪个实例执行其线程。


重要的是,我需要sleep在初始化每个线程后设置一秒以避免引发条件,我的意思是:等待所有线程启动并使所有线程处于等待状态。


输出:


T1 1

T2 2

T3 3

T1 4

T2 5

T3 6

T1 7

T2 8

T3 9

T1 10

T2 11

T3 12

T1 13

T2 14

T3 15

T1 16

T2 17

T3 18

T1 19

T2 20

T3 21

T1 22

T2 23

T3 24

T1 25

T2 26

T3 27

T1 28

T2 29

T3 30

--END--


查看完整回答
反对 回复 2023-07-19
?
慕少森

TA贡献2019条经验 获得超9个赞

只是为了学习,这就是强制顺序输出的方法。但请注意,不能以任何方式保证线程的顺序执行。正如其他人指出的那样,这个问题不适合多线程处理。如果您想按顺序执行某件事,请在一个线程中执行。


public class NumberGame {

    public static void main(String[] args) {


        PrintSequenceRunnable.startFrom("T1");


        new Thread(new PrintSequenceRunnable("T1", "T2")).start();

        new Thread(new PrintSequenceRunnable("T2", "T3")).start();

        new Thread(new PrintSequenceRunnable("T3", "T1")).start();

    }

}


class PrintSequenceRunnable implements Runnable {


    private final String name;

    private final String next;


    private static String moveTo;


    private static int value = 1;


    PrintSequenceRunnable(String name, String next) {

        this.name = name;

        this.next = next;

    }


    static void startFrom(String start) {

        moveTo = start;

    }


    private int uselessCounter = 0;


    @Override

    public void run() {

        do {

            synchronized (moveTo) {

                if (name.equals(moveTo)) {

                    System.out.println(name + "-" + (value++));

                    moveTo = next;

                } else {

                    uselessCounter++;

                }

            }

        } while (value < 10);

        System.out.println("Ran " + name + " uselessly for " + uselessCounter + " times."); // remove it.

    }


}


查看完整回答
反对 回复 2023-07-19
  • 2 回答
  • 0 关注
  • 114 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信