Написание программы с двумя потоками, которая печатает поочередно - PullRequest
8 голосов
/ 22 февраля 2012

Мне недавно задали этот вопрос в интервью.

Напишите программу с двумя потоками (A и B), где A печатает 1, B печатает 2 и так далее, пока не будет достигнуто 50.

Как нам это сделать?

Ответы [ 11 ]

9 голосов
/ 11 марта 2013

Суть назначения состоит в том, чтобы продемонстрировать, как поток может сигнализировать другому.Наиболее распространенный способ - использовать блокирующие очереди, но здесь сигнал не несет никакой информации, поэтому достаточно семафора.

Создать класс потока, параметризованный двумя семафорами: вход и выход:

class ThreadPrinter implements Runnable {
    int counter;
    Semaphore ins, outs;

    ThreadPrinter(int counter, Semaphore ins, Semaphore outs) {
        this.counter = counter;
        this.ins = ins;
        this.outs = outs;
    }

    @Override
    public void run() {
        for (int i = 0; i < 25; i++) {
            ins.aquire(); // wait for permission to run
            System.out.println("" + counter);
            outs.release();  // allow another thread to run
            counter += 2;
        }
    }

Создайте 2 Semaphore s и передайте их двум потокам:

Semaphore a = new Semaphore(1);  // first thread is allowed to run immediately
Semaphore b = new Semaphore(0); // second thread has to wait
ThreadPrinter tp1 = new ThreadPrinter(1, a, b);
ThreadPrinter tp2 = new ThreadPrinter(2, b, a); 

Примечание. Семафоры a и b передаются в другом порядке.

3 голосов
/ 09 января 2014
public class Test {

private static int count = 0;

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

    Thread t1 = new Thread(new Runnable() {

        @Override
        public void run() {

            for (int i = 0; i < 25; i++) {
                synchronized (CommonUtil.mLock) {
                    incrementCount();
                    CommonUtil.mLock.notify();
                    try {
                        CommonUtil.mLock.wait();
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        }
    });
    Thread t2 = new Thread(new Runnable() {

        @Override
        public void run() {

            for (int i = 0; i < 25; i++) {
                synchronized (CommonUtil.mLock) {
                    incrementCount();
                    CommonUtil.mLock.notify();
                    try {
                        CommonUtil.mLock.wait();
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        }
    });
    t1.start();
    Thread.sleep(400);
    t2.start();
    t1.join();
    t2.join();
}

private static void incrementCount() {

    count++;
    System.out.println("Count: " + count + " icnremented by: " +        Thread.currentThread().getName());
}
}
  class CommonUtil {

 static final Object mLock = new Object();
   }
2 голосов
/ 13 июня 2015

Я столкнулся с той же проблемой и должен был использовать только основы, поэтому я выбрал ожидание уведомления для общего объекта между потоками

public class Message implements Runnable {

    private static final int N = 10;
    private Thread thread;
    private static Object object = new Object();

    public Message(String name){
        thread = new Thread(this, name);
        thread.start();
    }

    public void run(){
        for(int i=0; i<N; i++){
            synchronized (object) {
                System.out.println(i + "--" + thread.getName());
                object.notify();
                try {
                    object.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
        }
    }
}

В основном методе:

Message message1 = new Message("Ping");
Message message2 = new Message("Pong");
0 голосов
/ 11 августа 2017
public class Testing implements Runnable {
private static int counter = 1;
private static final Object lock = new Object();

public static void main(String[] args)  {

    Thread t1 = new Thread(new Testing(), "1");
    t1.start();
    Thread t2 = new Thread(new Testing(), "2");
    t2.start();

}

@Override
public void run() {
    while (counter<=100) {
        synchronized (lock) {
            if (counter % 2 == 0) {
                System.out.println(counter +" Written By Thread-"+ Thread.currentThread().getName());
                counter++;
                try {
                    lock.notifyAll();
                    lock.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            } else if (counter % 2 == 1) {
                System.out.println(counter +" Written By Thread-"+ Thread.currentThread().getName());
                counter++;

                try {
                    lock.notifyAll();
                    lock.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
        }
    }
  }
}
0 голосов
/ 30 июня 2017
//simply use wait and notify and and set a counter and it will do  

public class ThreadalternatePrint implements Runnable {
    static int counter =0; 
    @Override
    public synchronized void run() {
        try {
            Thread.sleep(10);
        } catch (InterruptedException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }

        while(counter<51)
        {   ++counter;
        notify();
        System.out.println(Thread.currentThread().getName());
            try {
                    wait();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
        }       
    }

    public static void main(String[] args) {
        ThreadalternatePrint obj1 = new ThreadalternatePrint();
        Thread Th1 = new Thread(obj1);
        Thread Th2 = new Thread(obj1);
        Th1.setName("Thread1");
        Th2.setName("Thread2");
        Th1.start();
        Th2.start();
    }


}
0 голосов
/ 18 августа 2016

Это было самое простое решение, которое я смог придумать.Он использует синхронизированный метод и использует notify () и wait () для альтернативной печати чисел.Надеюсь, поможет.:)

 public class program implements Runnable
    {
        static int count =1;
        private static final int MAX_COUNT = 50;
        public synchronized void print ()
        {
            System.out.println(Thread.currentThread().getName() + " is printing " + count);
            count++;
            notify();
            try{
                if(count>MAX_COUNT)
                    return;
                wait();
            }catch (InterruptedException e){ 
                e.printStackTrace();
            }
        }
        public void run()
        {
            for(int i=0;i<MAX_COUNT/2;i++)
            {
                print();

            }
        }

        public static void main(String[] args) {

            program x= new program();
            Thread t0= new Thread(x);
            Thread t1=  new Thread(x);
            t0.start();
            try
            {
                Thread.sleep(1);
            } catch (InterruptedException e){
                e.printStackTrace();
            }
            t1.start();     
        }


    }
0 голосов
/ 17 марта 2015

Я думаю, это может помочь. Хотя это не стандартно, но я надеюсь, что это обеспечивает более простой подход.

public class ThreadDemo
{
    public static void main (String [] args)
    {
        PrintDemo pd=new PrintDemo();     
        MyThread1 mt1 = new MyThread1 ("T1",pd);
        MyThread2 mt2 = new MyThread2 ("T2",pd);     
        mt1.start ();
        mt2.start();
    }
}
class PrintDemo {
    private boolean oddFlag=true;
    public synchronized void printOdd(int i,String tName){
        if(oddFlag==false){
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }   
        }else{
            System.out.println("\nThread "+tName+" count:"+i);
            oddFlag=false;
            notify();
        }
    }
    public synchronized void printEven(int i,String tName){
        if(oddFlag==true){
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }   
        }else{
            System.out.println("\nThread "+tName+" count:"+i);
            oddFlag=true;
            notify();
        }
    }   
}
class MyThread1 extends Thread
{
    private PrintDemo pd;
    private String name;

    MyThread1(String threadName,PrintDemo pd){
        this.name=threadName;
        this.pd=pd;
    }  
    public void run ()  
    {
       for(int i=1;i<=50;i+=2){
            pd.printOdd(i,name);
       }
    }
}
class MyThread2 extends Thread
{
    private PrintDemo pd;
    private String name;    
    MyThread2(String threadName,PrintDemo pd){
        this.name=threadName;
        this.pd=pd;
    }   
    public void run ()
    {
        for(int i=2;i<=50;i+=2){
            pd.printEven(i,name);                   
        }
    }
}
0 голосов
/ 13 февраля 2014
public class ThreadCounter implements Runnable {
    private static int count = 0;

    private Thread t;

    public ThreadCounter(String tName){
        t= new Thread(this, tName);
        t.start();
    }

    @Override
    public void run() {
        for(int i=1; i<=5; i++){
            synchronized (CommonUtil.mLock) {
                incrementCount(t.getName());
                CommonUtil.mLock.notify();
                try {
                    CommonUtil.mLock.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private void incrementCount(String tName){
        System.out.println(tName+": "+(++ThreadCounter.count));
    }

    public static void main(String[] args) throws InterruptedException {
        new ThreadCounter("Thread1");
        Thread.sleep(500);
        new ThreadCounter("Thread2");
    }

}

class CommonUtil{
    public static Object mLock = new Object();
}
0 голосов
/ 11 марта 2013
public class PingPong extends Thread {
static StringBuilder object = new StringBuilder("");

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

    Thread t1 = new PingPong();
    Thread t2 = new PingPong();

    t1.setName("\nping");
    t2.setName(" pong");

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

@Override
public void run() {
    working();
}

void working() {
    while (true) {
        synchronized (object) {
            try {
                System.out.print(Thread.currentThread().getName());
                object.notify();
                object.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

}

0 голосов
/ 04 марта 2013

Может быть, это все еще актуально:

public class MyRunnable implements Runnable {
    public static int counter = 0;
    public static int turn = 0;
    public static Object lock = new Object();

    @Override
    public void run() {
        while (counter < 50) {
            synchronized (lock) {
                if (turn == 0) {

                    System.out.println(counter + " from thread "
                            + Thread.currentThread().getName());
                    turn = 1;
                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                    }
                } else {
                    turn = 0;
                    lock.notify();
                }

            }
        }
    }
}

, а затем основная функция

public static void main(String[] args) {
        Thread threadA = new Thread(new MyRunnable());
        Thread threadB = new Thread(new MyRunnable ());
        threadA.start();
        threadB.start();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...