2012-02-22 15 views
5

Me hicieron esta pregunta recientemente en una entrevista.Escribiendo un programa con 2 hilos que imprime alternativamente

Escriba un programa con dos hilos (A y B), donde A imprime 1, B imprime 2 y así sucesivamente hasta llegar a 50.

¿Cómo hacemos para eso?

+4

¿Usted sabe cómo escribir un programa con dos hilos? Si no, mira tu tutorial favorito para enhebrar. Si es así, intente escribir tal programa y vea qué sucede. –

+0

¿Es esto una tarea/tarea? –

+3

Por cierto, si hice esta pregunta en una entrevista, espero que el solicitante mencione que esto es algo bastante estúpido de tratar de hacer con dos hilos.No está mal como una prueba de comprensión de las API de subprocesamiento, pero básicamente estás pidiendo a dos subprocesos que actúen de una sola vez. – yshavit

Respuesta

0

Esta es otra solución:

 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

puede ser esto sigue siendo relevante:

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

      } 
     } 
    } 
} 

y luego la función principal

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

La esencia de la tarea es demostrar cómo un hilo puede señalar a otro. La forma más común es usar colas de bloqueo, pero aquí una señal no contiene información, por lo que un semáforo es suficiente.

Crear clase hilo que se parametriza con 2 Semáforos: entrada y salida:

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

Crear 2 Semaphore s y pasarlos a 2 hilos:

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

Nota semáforos a y b se pasan en diferente orden

+0

Esto está funcionando perfecto. Pero estoy enfrentando dificultades para entender cómo está funcionando. ¿Puedes explicar la ejecución del método run() por 2 hilos? Gracias por adelantado. –

+1

@PradeepSingh lee cualquier libro de texto que describa semáforos. Prefiero aquellos que representan un semáforo como contenedor de tokens. –

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

supongo que esto podría ayudar. Aunque no es estándar, espero que proporcione un enfoque más simple.

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

me encontré con el mismo problema y se espera que utilice sólo lo básico, así que decido esperar notificar el objeto compartido entre hilos

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

      } 
     } 
    } 
} 

En el método principal:

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

Ésta fue la la solución más simple, fui capaz de pensar. Utiliza un método sincronizado y usa notify() y wait() para imprimir alternativamente los números. Espero eso ayude. :)

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

Su guinda es objetivamente incorrecta (imprima el nombre del hilo en lugar de 1,2,3, ...), y quizás quiera explicar su código un poco, en lugar de simplemente arrojar todo su código. – glee8e

+0

@ glee8e Gracias por los comentarios, explicaré el código a continuación. Bueno, es solo una simple implementación del método de subprocesos simplemente puede cambiar el nombre de los hilos a 1 o 2 y usar wait() y notificar que puede notificar() el otro hilo e imprimir de forma alternativa otra cosa que puede hacer es crear un si condición con nombre de hilo en la condición de ejecución. –

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

hay bastante código aquí. Deberías considerar dar una explicación de eso. – ADyson

Cuestiones relacionadas