2017-01-25 12 views
-2

このプログラムを実行するたびに、毎回異なる出力が得られます。 runメソッドでのみ一貫した出力を得る方法はありますか?runメソッドとsynchronizedを併用しないでください。

public class MultiBasic1 { 

    public static void main(String[] args) { 
     ChildThread th1=new ChildThread(); 
     ChildThread th2= new ChildThread(); 
     ChildThread th3= new ChildThread(); 
     ChildThread th4= new ChildThread(); 
     th1.start(); 
     th2.start(); 
     th3.start(); 
     th4.start(); 
    } 
} 

class ChildThread extends Thread{ 

    synchronized public void run(){ 
     for(int i=1; i<=5; i++) 
      System.out.println(i); 
    } 
} 
+2

*「実行メソッドで一貫性のある出力を得る機会はありますか?」 - スレッドを使用せず、直接 'run'を呼び出します – MadProgrammer

+0

@MadProgrammer直接実行した場合、マルチスレッド化のメリットは得られません。 –

+5

一度に「実行」できるスレッドは1つだけですが、マルチスレッド化のメリットも得られません。 – user2357112

答えて

2

あなたがChildThreadの新しいインスタンスを作成しているので、実際にメソッドにアクセスする唯一のスレッドがあるとして、各スレッドは、制限なくrunメソッドにアクセスすることを許可されています。

は​​作品は、あなたが各スレッドは、上記の例では、1つのスレッドしか内で実行できることを実証している

public class Test { 

    public static void main(String[] args) { 
     Action action = new Action(); 
     Thread t1 = new Thread(new Runner(action), "1"); 
     Thread t2 = new Thread(new Runner(action), "2"); 
     Thread t3 = new Thread(new Runner(action), "3"); 
     Thread t4 = new Thread(new Runner(action), "4"); 
     Thread t5 = new Thread(new Runner(action), "5"); 


     t1.start(); 
     t2.start(); 
     t3.start(); 
     t4.start(); 
     t5.start(); 
    } 

    public static class Runner implements Runnable { 
     private Action action; 

     public Runner(Action action) { 
      this.action = action; 
     } 

     @Override 
     public void run() { 
      action.makeItSo(); 
     } 

    } 

    public static class Action { 
     public synchronized void makeItSo() { 
      for (int index = 0; index < 10; index++) { 
       System.out.println(Thread.currentThread().getName() + " - " + index); 
      } 
     } 
    } 

} 

と相互作用することができるようにObjectなどいくつかの種類の共有リソースを、持っている必要があるだろうか実証するために、 makeItSoメソッドだけでなく、実行できるスレッド(つまり、注文)の保証もありません。

0

runメソッドを呼び出すために異なるオブジェクトを使用しているため、ここでは同期の必要はありません。

同期は、1つのオブジェクトの複数のスレッドが画像内にある場合に機能します。

上記の例は、次のようなことを行うと意味があります。

public class MultiBasic1 { 

    public static void main(String[] args) { 
     ChildThread th1=new ChildThread(); 
     Thread t1 = new Thread(th1); 
     Thread t2 = new Thread(th1); 
     Thread t3 = new Thread(th1); 
     Thread t4 = new Thread(th1); 
     t1.start(); 
     t2.start(); 
     t3.start(); 
     t4.start(); 
    } 
} 

class ChildThread extends Thread{ 

    synchronized public void run(){ 
     for(int i=1; i<=5; i++) 
      System.out.println(i); 
    } 
} 
1

なぜ出力が異なるのですか?

回答: synchronized同期化されたブロックまたはメソッドに入る前に、ロックが達成されたオブジェクトが必要です。

この場合、メソッドが実行されるオブジェクトでロックが達成されているため、スレッド1はオブジェクトth1でロックされ、スレッド2はth2でロックされます。

したがって、すべてのスレッドは異なるオブジェクトにロックされており、同時に実行することができます。

一貫した出力を得るにはどうすればよいですか?

回答

オプション1:あなたがメインスレッドに パブリッククラスMultiBasic1をスレッドに参加する参加使用することができます{

public static void main(String[] args) throws InterruptedException { 
    ChildThread th1=new ChildThread(); 
    ChildThread th2= new ChildThread(); 
    ChildThread th3= new ChildThread(); 
    ChildThread th4= new ChildThread(); 

    th1.setName("A"); 
    th2.setName("B"); 
    th3.setName("C"); 
    th4.setName("D"); 

    th1.start(); 
    th1.join(); 
    th2.start(); 
    th2.join(); 
    th3.start(); 
    th3.join(); 
    th4.start(); 
    th4.join(); 
} 

}

クラスChildThreadが延びスレッド{

public void run(){ 
    for(int i=1; i<=5; i++) 
     System.out.println(i + " " + getName()); 
} 

}

オプション2:スレッド

パブリッククラスMultiBasic1 {

public static void main(String[] args) throws InterruptedException { 
    ChildThread th1=new ChildThread(); 
    ChildThread th2= new ChildThread(); 
    ChildThread th3= new ChildThread(); 
    ChildThread th4= new ChildThread(); 

    th1.setName("A"); 
    th2.setName("B"); 
    th3.setName("C"); 
    th4.setName("D"); 

    th1.start(); 
    th2.start(); 
    th3.start(); 
    th4.start(); 
} 

}

クラスChildThreadスレッド{

private static final Object lock = new Object(); 
public void run(){ 

    synchronized (lock) { 
     for(int i=1; i<=5; i++) 
      System.out.println(i + " " + getName()); 
    } 

} 

}

を拡張を同期するために同期化ブロックの共有オブジェクトを提供
関連する問題