簡體   English   中英

使用多線程打印字母和數字

[英]Printing Alphabets and Numbers using multi-threading

我剛剛開始學習線程並且對它很陌生。我正在嘗試一個接一個地打印字母和數字。我已經使用標志同步它們但沒有用。

public class Alphabets {

    public static void main(String[] args) {

              AN an= new AN(false);

              Thread t1=new Thread(new Runnable() {

                @Override
                public void run() {

                    try {

                        an.Alpha();
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            });


              Thread t2= new Thread(new Runnable() {

                @Override
                public void run() {
                    try {
                        an.numbers();
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }

                }
            });


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

}

...

 class AN
    {

        boolean flag;

        AN(boolean flag)
        {
            this.flag=flag;
        }
        synchronized void Alpha() throws InterruptedException
        {
            if(flag==false)
            {
            for(char i='A'; i<='Z';i++)
            {
                System.out.println(+i);
                notifyAll();
                flag=true;
            }
            }
            else
            {
                wait();
            }

        }

        synchronized void numbers() throws InterruptedException
        {
            if(flag==true)
            {
            for(int i=1;i<=26;i++)
            {
                System.out.println(+i);
                notifyAll();
                flag=false;
            }
            }
            else
            {
                wait();
            }
        }


    }

我想要的輸出是:a1b2c3d4....

我的控制台輸出是:abcd...1234...

任何人都可以指出錯誤,因為我無法同步這兩個線程。

更改類 AN 以檢查 while 循環中的標志。

public class AN {
  boolean flag;

  AN(boolean flag) {
    this.flag = flag;
  }

  synchronized void Alpha() throws InterruptedException {

    for(char i = 'A'; i <= 'Z'; i++) {
      while(flag == true) {
        wait();
      }
      System.out.println(i);
      notifyAll();
      flag = true;
    }
  }

  synchronized void numbers() throws InterruptedException {

    for(int i = 1; i <= 26; i++) {
      while(flag == false) {
        wait();
      }
      System.out.println(i);
      notifyAll();
      flag = false;
    }
  }

好吧,您想要的或多或少是流水線,因此線程需要知道何時允許它們工作。

因此,我會使用隊列來等待一個線程上的輸入並等待它在另一個線程中設置。

AN 類:

import java.util.concurrent.BlockingQueue;

class AN
{

    BlockingQueue<Boolean> input;

    BlockingQueue<Boolean> output;

    AN(BlockingQueue<Boolean> input, BlockingQueue<Boolean> output)
    {

        this.input = input;
        this.output = output;
    }

    void Alpha() throws InterruptedException
    {
        for (char i = 'a'; i <= 'z'; i++) {
            input.take();
            System.out.print(i);
            output.put(Boolean.TRUE);

        }
    }

    void numbers() throws InterruptedException
    {
        for (int i = 1; i <= 26; i++) {
            input.take();
            System.out.print(i);
            output.put(Boolean.TRUE);
        }

    }

}

類測試(或你的主要在哪里):

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

public class Test
{

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

        BlockingQueue<Boolean> input = new LinkedBlockingQueue<>();
        BlockingQueue<Boolean> output = new LinkedBlockingQueue<>();

        AN an1 = new AN(output, input);
        AN an2 = new AN(input, output);
        output.add(Boolean.TRUE);

        Thread t1 = new Thread(new Runnable()
        {

            @Override
            public void run()
            {
                try {
                    an1.Alpha();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        });

        Thread t2 = new Thread(new Runnable()
        {

            @Override
            public void run()
            {
                try {
                    an2.numbers();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

            }
        });

        t1.start();
        t2.start();

    }
}

輸出: a1b2c3d4e5f6g7h8i9j10k11l12m13n14o15p16q17r18s19t20u21v22w23x24y25z26

您可以通過使用 BlockingQueue 和 Object 的 wait 和 notify 方法來實現這一點。

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


    BlockingQueue<String> queue = new ArrayBlockingQueue<String>(10);

    AtomicBoolean flag = new AtomicBoolean(Boolean.TRUE);

    Object lock = new Object();

    Thread t1 = new Thread(new Runnable() {
        @Override
        public void run() {

            try {
                for(int i=1;i<=26;i++){
                        synchronized (lock){
                            while (flag.get()){
                                lock.wait();
                            }
                            System.out.print(i);
                            flag.set(Boolean.TRUE);
                            lock.notify();
                    }
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    });

    Thread t2 = new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                for(char c='A';c<='Z';c++){
                    synchronized (lock){
                        while (!flag.get()){
                            lock.wait();
                        }
                        System.out.print(c);
                        flag.set(Boolean.FALSE);
                        lock.notify();
                    }
                }

            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    });


    t1.start();
    t2.start();

    }
}

上面的代碼打印 a1b2c3d4.......z26

有很多方法可以實現這一點,下面是其中之一。

package interview;

public class TestAplhaAndNumberPrinterThreads {

    // created object as static so we can access print method of this class from thread's run methods
    public static TestAplhaAndNumberPrinterThreads output = new TestAplhaAndNumberPrinterThreads();

    private final Object syncer = new Object();
    private int state = 0;

    public void print(char character) throws InterruptedException {
        synchronized (syncer) {
            while (true) {
                if (state == 0) {
                    System.out.print(character + ", ");
                    state = 1;
                    syncer.notify();
                    return;
                } else {
                    syncer.wait();
                }
            }
        }
    }

    public void print(int number) throws InterruptedException {
        synchronized (syncer) {
            while (true) {
                if (state == 1) {
                    System.out.print(number + ", ");
                    state = 0;
                    syncer.notify();
                    return;
                } else {
                    syncer.wait();
                }
            }
        }
    }

    public static void main(String[] args) {
        NumberPrinter numberPrinter = new NumberPrinter();
        AlphabetsPrinter alphabetsPrinter = new AlphabetsPrinter();
        numberPrinter.start();
        alphabetsPrinter.start();
    }
}

class NumberPrinter extends Thread {

    @Override
    public void run() {
        try {
            for (int i = 1; i <= 26; i++) {
                TestAplhaAndNumberPrinterThreads.output.print(i);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

class AlphabetsPrinter extends Thread {

    @Override
    public void run() {
        try {
            for (char i = 'a'; i <= 'z'; i++) {
                TestAplhaAndNumberPrinterThreads.output.print(i);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

// output: a, 1, b, 2, c, 3, d, 4, e, 5, f, 6, g, 7, h, 8, i, 9, j, 10, k, 11, l, 12, m, 13, n, 14, o, 15, p, 16, q, 17, r, 18, s, 19, t, 20, u, 21, v, 22, w, 23, x, 24, y, 25, z, 26,

對你來說,我認為最重要的是,你需要知道如何使用 breakPoint 在 ide 中進行調試,然后你就會明白為什么你的代碼不起作用。 您可以看到您的代碼將運行的過程我在最后發布了圖片,我與您分享了這段代碼,它將按照您的意願工作

class AN {

boolean flag;

AN(boolean flag) {
    this.flag = flag;
}

synchronized void Alpha() throws InterruptedException {
    if (flag == false) {
        for (char i = 'A'; i <= 'Z'; i++) {
            System.out.println(i);
            flag = true;
            notify();
            wait();
        }
    }

}

synchronized void numbers() throws InterruptedException {
    if (flag == true) {
        for (int i = 1; i <= 26; i++) {
            System.out.println(+i);
            flag = false;
            notify();
            wait();
        }
    }
}

}

在此處輸入圖像描述

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM