简体   繁体   English

使用多线程打印字母和数字

[英]Printing Alphabets and Numbers using multi-threading

I have just started learning threads and pretty new to it.I'm trying to print alphabets and numbers one after the other.I have synchronized them using a flag but of no use.我刚刚开始学习线程并且对它很陌生。我正在尝试一个接一个地打印字母和数字。我已经使用标志同步它们但没有用。

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


    }

My desired output is : a1b2c3d4....我想要的输出是:a1b2c3d4....

My console output is : abcd...1234...我的控制台输出是:abcd...1234...

Can anybody point out the mistake since I'm unable to synchronize these two threads.任何人都可以指出错误,因为我无法同步这两个线程。

Change class AN to check the flag in while loop.更改类 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;
    }
  }

Well, what you want is more or less pipelining, therefore the threads need to know when they are allowed to work.好吧,您想要的或多或少是流水线,因此线程需要知道何时允许它们工作。

I'd therefore use a Queue to await the input on one thread and wait for it to be set in the other thread.因此,我会使用队列来等待一个线程上的输入并等待它在另一个线程中设置。

Class AN: 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);
        }

    }

}

Class Test (or where your main is):类测试(或你的主要在哪里):

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

    }
}

Outputs: a1b2c3d4e5f6g7h8i9j10k11l12m13n14o15p16q17r18s19t20u21v22w23x24y25z26输出: a1b2c3d4e5f6g7h8i9j10k11l12m13n14o15p16q17r18s19t20u21v22w23x24y25z26

You can achieve this by using BlockingQueue and Object's wait and notify methods.您可以通过使用 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();

    }
}

The above code prints a1b2c3d4.......z26上面的代码打印 a1b2c3d4.......z26

There are many ways to achieve this, Below one is one of them.有很多方法可以实现这一点,下面是其中之一。

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,

For you i think the big things is , you need to know how to use breakPoint to debug in ide , and than you will see why your code not work.对你来说,我认为最重要的是,你需要知道如何使用 breakPoint 在 ide 中进行调试,然后你就会明白为什么你的代码不起作用。 you can see the process of your code will run i post the picture in the last , and i share you this code which will work like your wish您可以看到您的代码将运行的过程我在最后发布了图片,我与您分享了这段代码,它将按照您的意愿工作

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

} }

enter image description here在此处输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM