编写一个带有2个线程的程序,可以交替打印

时间:2012-02-22 03:49:34

标签: java multithreading concurrency

我最近在接受采访时被问到这个问题。

  

编写一个带有两个线程(A和B)的程序,其中A打印1,B打印2,依此类推,直到达到50。

我们如何做到这一点?

14 个答案:

答案 0 :(得分:9)

赋值的本质是演示线程如何发出另一个信号。最常见的方法是使用阻塞队列,但这里信号不携带任何信息,因此信号量就足够了。

创建用2个信号量参数化的线程类:输入和输出:

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并将它们传递给2个主题:

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

注意信号量ab以不同的顺序传递。

答案 1 :(得分:3)

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 :(得分:2)

我遇到了同样的问题,并且预计只使用基础知识,所以我选择在线程之间的共享对象上等待通知

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

答案 3 :(得分:1)

嗨,请在这里找到答案...模式ABABABAB

package com.abhi.ThreadPractice;

    public class Test {

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

          final Object lock = new Object();
          Thread t1 = new Thread(new Runnable() {

            @Override
           public void run() {
            for (int i = 0; i < 10; i++) {

              synchronized (lock) {
             // count++;
              System.out.println("A");
              try {
               lock.wait();
               lock.notify();
              } catch (InterruptedException e) {
               e.printStackTrace();
              }
             }
            }
           }
          });             

           Thread t2 = new Thread(new Runnable() {

            @Override
           public void run() {
            for (int i = 0; i < 10; i++) {
             synchronized (lock) {
              lock.notify();
              //count++;
              System.out.println("B");
              try {
               lock.wait();
              } catch (InterruptedException e) {
               e.printStackTrace();
              }
             }
            }
           }
          });

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

          }

        }

答案 4 :(得分:0)

这是另一种解决方案:

     Thread t1 = new Thread(new Runnable() {

        @Override
        public void run() {
            synchronized (lock) {
                for (int i = 1; i <= 50; i += 2) {
                    System.out.println("T1=" + i);

                    t1turn = false;
                        try {
                            lock.notifyAll();
                            lock.wait();
                        } catch (InterruptedException e) {
                        }
                }
            }

        }
    });
    Thread t2 = new Thread(new Runnable() {

        @Override
        public void run() {
            synchronized (lock) {
                for (int i = 2; i <= 50; i += 2) {
                    if (t1turn)
                        try {
                            lock.wait();
                        } catch (InterruptedException e) {
                        }
                    System.out.println("T2=" + i);
                    t1turn = true;
                    lock.notify();
                }
            }
        }
    });
    t1.start();
    t2.start();

答案 5 :(得分:0)

可能这仍然是相关的:

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

答案 6 :(得分:0)

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

}

答案 7 :(得分:0)

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

答案 8 :(得分:0)

这是最简单的解决方案,我能够想到。它使用synchronized方法并使用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();     
        }


    }

答案 9 :(得分:0)

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


}

答案 10 :(得分:0)

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

            }
        }
    }
  }
}

答案 11 :(得分:0)

我使用可重入锁为它创建了一个非常基本的解决方案。

package com.multithreding.trylock;

import java.util.concurrent.locks.ReentrantLock;

public class TryLock extends Thread {

    static int intitialCount = 50;          //Value till which you want to print
    int valueToSubtract = 0;                //Value by which difference you want to print the series like 1,2,3
    static ReentrantLock alternate = new ReentrantLock();

    public TryLock(String name) {
        this.setName(name);
    }

    public void run() {
        while (intitialCount > 1) {         

            if (valueToSubtract > 0) {
                alternate.lock();
                intitialCount = intitialCount - valueToSubtract;
                valueToSubtract = 0;
                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                System.out.println("value Subtracted " + intitialCount + " by the Thread" + this.getName());
                alternate.unlock();
            } else {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                valueToSubtract++;
            }
        }

    }

}

package com.multithreding.trylock;

public class AlternatePrint {

    public static void main(String[] args) throws InterruptedException{
        //You  can add as many thread to print then in different number of series
        TryLock t1 = new TryLock("Odd One");
        TryLock t2 = new TryLock("Even Value");
        t1.start();
        t2.start();

    }

}

该解决方案也是模块化的,

  • 您可以添加“ n”个线程来打印备用系列。即一次使用3个线程

  • 您还可以打印“差值大于1”的系列,即1,3,5等

答案 12 :(得分:0)

package thread;

public class Pingpong extends Thread {
    static StringBuilder object = new StringBuilder("");
    static int i=1;

    @Override
    public void run() {
        working();
    }
    void working() {
        while (i<=10) {
            synchronized (object) {
                try {
                    System.out.println(Thread.currentThread().getName() +"  "+ i);
                    i++;
                    object.notify();
                    object.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Pingpong();
        Thread t2 = new Pingpong();
        t1.setName("Thread1");
        t2.setName("Thread2");
        t1.start();
        t2.start();
    }
}

Thread1  1
Thread2  2
Thread1  3
Thread2  4
Thread1  5
Thread2  6
Thread1  7
Thread2  8
Thread1  9
Thread2  10

答案 13 :(得分:-1)

我想这可能会有所帮助。 虽然它不是标准的,但我希望它提供了一种更简单的方法。

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