2012-02-22 49 views
5

最近我在一次採訪中被問到了這個問題。用2個線程編寫一個程序,它可以打印出來

用兩個線程(A和B)編寫程序,其中A打印1,B打印2等,直到達到50。

我們該如何去做?

+4

你知道如何編寫一個程序,兩個線程?如果沒有,請參閱您最喜歡的線程教程。如果是這樣,那麼嘗試編寫這樣一個程序,看看會發生什麼。 – 2012-02-22 03:54:29

+0

這是作業/作業嗎? – 2012-02-22 03:54:37

+3

順便說一句,如果我在面試中問這個問題,我希望申請人會提到這是一個非常愚蠢的事情,試圖用兩個線程。作爲理解線程API的測試並不差,但基本上要求兩個線程以單線程方式運行。 – yshavit 2012-02-22 05:54:58

回答

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

}

8

作業的本質是演示一個線程如何發出另一個線程的信號。最常用的方法是使用阻塞隊列,但這裏的信號不帶任何信息,因此信號量就足夠了。

創建其參數與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 S和它們傳遞到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被傳遞以不同的順序。

+0

這是工作完美。但是我很難理解它是如何工作的。你能解釋一下run()方法執行2個線程嗎?提前致謝。 – 2017-06-29 18:59:23

+1

@PradeepSingh閱讀描述信號量的任何教科書。優先考慮將信號量作爲令牌容器的圖片。 – 2017-06-29 23:05:18

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

我遇到同樣的問題,預計所以我選擇等待通知線程

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

      } 
     } 
    } 
} 

在main方法之間共享對象只使用基本知識:

Message message1 = new Message("Ping"); 
Message message2 = new Message("Pong"); 
0

這是最簡單的解決方案,我能夠想到。它使用同步方法並使用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
//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(); 
    } 


} 
+1

你的anwser實際上是不正確的(打印線程名稱而不是1,2,3,...),你可能想要解釋一下你的代碼,而不是僅僅傾銷你的所有代碼。 – glee8e 2017-07-01 06:05:29

+0

@ glee8e感謝您的反饋,我會解釋下面的代碼。 以及它只是簡單的線程方法實現,你可以簡單地重命名爲Thread的線程爲1或2,並使用wait()並通知您可以通知()另一個線程並交替打印 您可以做的另一件事是創建一個如果條件與線程名稱在運行條件。 – 2017-07-03 03:14:53

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

      } 
     } 
    } 
    } 
} 
+0

這裏有相當多的代碼。你應該考慮給出一個解釋。 – ADyson 2017-08-11 12:33:59

相關問題