2012-02-22 6 views
5

Ho ricevuto questa domanda di recente in un'intervista.Scrittura di un programma con 2 thread che vengono stampati alternativamente

Scrivere un programma con due fili (A e B), dove A stampa 1, B stampa 2 e così via fino a raggiungere 50.

Come facciamo a farlo?

+4

Sai come scrivere un programma con due fili? In caso contrario, guarda il tuo tutorial di threading preferito. Se è così, prova a scrivere un programma del genere e guarda cosa succede. –

+0

È un compito a casa/compito? –

+3

Btw, se avessi fatto questa domanda in un'intervista, mi auguro che il richiedente possa dire che questa è una cosa piuttosto stupida da provare con due thread.Non è male come test di comprensione delle API di threading, ma fondamentalmente stai chiedendo a due thread di agire in modo single-thread. – yshavit

risposta

0

Questa è un'altra soluzione:

 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

Può essere questo è ancora di attualità:

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

      } 
     } 
    } 
} 

e quindi la funzione principale

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

L'essenza del compito è dimostrare come un thread può segnalarne un altro. Il modo più comune è usare le code di blocco, ma qui un segnale non porta alcuna informazione, quindi un semaforo è sufficiente.

Crea classe thread che è parametrizzato con 2 semafori: ingresso e uscita:

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

Crea 2 Semaphore s e passarle a 2 fili:

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

Note semafori a e b vengono passati in ordine diverso.

+0

Funziona perfettamente. Ma sto affrontando difficoltà nel comprenderlo come funziona. Potete spiegarlo per favore l'esecuzione del metodo run() con 2 thread. Grazie in anticipo. –

+1

@PradeepSingh legge qualsiasi libro di testo che descrive i semafori. Preferisci quelli che immaginano un semaforo come un contenitore di gettoni. –

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

credo che questo potrebbe aiutare. Sebbene non sia standard, spero che fornisca un approccio più semplice.

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

ho incontrato lo stesso problema e si è pensato di utilizzare solo nozioni di base così ho scelto di attendere notifica sul oggetto condiviso tra i thread

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

      } 
     } 
    } 
} 

Nel metodo main:

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

Questa è stata la la soluzione più semplice, sono stato in grado di pensare. Usa un metodo sincronizzato e usa il notify() e il wait() per stampare alternativamente i numeri. Spero che sia d'aiuto. :)

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

Il tuo anwser è effettivamente errato (nome del filetto di stampa invece di 1,2,3, ...), e potresti voler spiegare un po 'il tuo codice, invece di scaricare tutto il codice. – glee8e

+0

@ glee8e grazie per il feedback, spiegherò il codice qui sotto. beh è solo semplice implementazione del metodo thread puoi semplicemente rinominare i nomi in Thread su 1 o 2 e usare wait() e notificare puoi notificare() l'altro thread e stampare alternativamente un'altra cosa che puoi fare è creare un se condizione con nome thread nella condizione di esecuzione. –

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

qui c'è un bel po 'di codice. Dovresti considerare di dargli una spiegazione. – ADyson

Problemi correlati