亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何使用多線程打印序列中的數字

如何使用多線程打印序列中的數字

智慧大石 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 關注
  • 149 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號