2011-01-13 9 views
5

Tengo una clase Note y una clase Meeting. Hay un ArrayList llamado noteList en la clase Note. Cuando se crea un objeto de Meeting, se registra en el noteList.cómo iniciar dos hilos al mismo tiempo (o en el momento de cierre)

Solo quiero demostrar en la clase principal que se pueden crear dos objetos de Meeting al mismo tiempo (o en el momento de cerrarlo). Mi programa es:

public class Note{ 
    //some field and method hier 
    public void add(Meeting m){ 
     notes.add(m); 
    } 
    private static final List<Entry> notes = 
     Collections.synchronizedList(new ArrayList<Entry>()); 
} 

public class Meeting implements Runnable{ 
    public Meeting(Note note_1,Note note_2,Calendar calendar){ 
     note_1.add(this); 
     note_2.add(this);} 
     //some method 
    } 

    public class Test implements Runnable{ 
     public static void main(String[] args) { 
      Note note_1 = new Note();     
      Note note_2 = new Note(); 
      Meeting m_1 = new Meeting(note_1,note_2); 
      Meeting m_2 = new Meeting(note_2,note_1) 
      Thread t1 = new Thread(m_1); 
      Thread t2 = new Thread(m_2) 
      t1.start(); 
      t2.start(); 
     } 
     //t1,t2 are two thread and they start one to one(not at the same time). 

He leído en cualquier lugar que wait(), notify() o notifyAll() se puede utilizar, pero debe ser utilizado en un método sincronizado. No tengo métodos sincronizados en mi programa.

+0

En su código como está escrito, 'm_1' siempre se crea (instancia) antes de' m_2' aunque serán tanto existir simultáneamente en memoria hasta que el GC decide limpiarlos. ¿Te refieres a algo más? En cualquier caso, si busca por qué no funciona el doble bloqueo comprobado para singletons obtendrá una muy buena visión general de los problemas de sincronización en Java. – CurtainDog

+0

Creo que falta.Me refiero a cómo se pueden crear m_1 y m_2 (crear instancias) al mismo tiempo (o en el momento del cierre) – echo

+0

Está utilizando métodos sincronizados porque synchronizedList() devuelve una lista que tiene todo su método sincronizado. –

Respuesta

15

Esto es lo más cerca que podrá llegar a comenzar los dos hilos.

Lo que podría hacer para sincronizar los métodos de ejecución aún más es tenerlos esperando en un CountDownLatch en la parte superior de sus métodos de ejecución.

Lo que hace es quitar la sobrecarga de crear e iniciar Threads (la parte que ocurre antes de que se ejecute su método de ejecución), y tal vez también algunas extravagancias de programación anormales. Sin embargo, no tiene garantía de cuán concurrente se ejecutará el código después del enganche.

CountDownLatch latch = new CountDownLatch(2); 

Runnable r1 = new Meeting(latch); 
Runnable r2 = new Meeting(latch); 


// in Meeting 

private final CountDownLatch latch; 

public void run(){ 

    latch.countDown(); 
    latch.await(); 

    // other code 
} 
+1

+1 Vea también, http://stackoverflow.com/questions/1909622 – trashgod

+0

Usted solo puede garantizar que un hilo no se aguarde hasta que el segundo alcance countDown. Esto asegura que ambos comiencen pero uno podría dejar de funcionar inmediatamente después. –

+0

@ Peter Lawrey: Sí, eso es lo que quise decir con "no tiene garantía, sin embargo, de cuán concurrente se ejecutará realmente el código después del enganche". Todo lo que puede hacer cumplir es un ordenamiento estricto, si así lo desea. – Thilo

8

Desafortunadamente, no hay manera de comenzar dos hilos al mismo tiempo.

Déjame explicarte mejor: en primer lugar, la secuencia t1.Start(); y t2.Start(); se ejecuta primero con t1 y, después de eso, t2. Significa solo que el hilo t1 está programado antes de hilo 2, realmente no iniciado. Los dos métodos toman fracciones de segundo cada uno, por lo que el hecho de que estén en secuencia no puede ser visto por un observador humano.

Más, los hilos de Java son programado, es decir. asignado para ser eventualmente ejecutado. Incluso si tiene una CPU multinúcleo, no está seguro de que 1) los hilos se ejecuten en paralelo (otros procesos del sistema puedan interferir) y 2) los hilos comiencen justo después de que se llame al método Start().

+1

No puede iniciar dos subprocesos al mismo tiempo, pero puede sincronizar en el método de ejecución. Por supuesto, todo lo que dijiste sobre la eventual ejecución aún se aplica. Pero al menos puede coordinar la secuencia en la que se ejecutan los métodos de ejecución, en caso de que exista alguna interdependencia. – Thilo

+0

Cuando se trabaja con subprocesos y/o CPUs múltiples, realmente no hay nada como 'al mismo tiempo'. Debes aclarar tu pregunta. – EJP

1

Están comenzando desde "cerrar" al mismo tiempo. El punto es que su código no está bloqueando al t1.start().

Es posible que pueda ver esto agregando una instrucción de impresión en la parte superior del método run() de la clase Meeting, y otra instrucción de impresión justo después de t2.start(). Algo como esto:

public class Meeting implements Runnable { 
    private String name; 
    public Meeting(String name) { 
     this.name = name; 
    } 
    public void run() { 
     System.out.println(name + " is running"); 
    } 
} 

public class Test { 
    public static void main(String[] args) { 
     Meeting m_1 = new Meeting("meeting 1"); 
     Meeting m_2 = new Meeting("meeting 2") 
     Thread t1 = new Thread(m_1); 
     Thread t2 = new Thread(m_2) 
     t1.start(); 
     t2.start(); 
     System.out.println("this might print first!"); 
    } 
} 

// possible output: 
> this might print first! 
> meeting 1 is running 
> meeting 2 is running 
Cuestiones relacionadas