0

私のプログラムは以下のようになります

  1. メインプログラム (スレッド 1)
  2. 複数の単純な Java スレッドを作成する (Thead 1.1、1.2...)
  3. 各スレッド(1.1または1.2 ..)で、応答していないことがある1つのメソッド(CORBA呼び出し)を呼び出す処理も行っています。このメソッドのタイマーを定義したいのですが、スレッド(呼び出している人は誰でも1.1または1.2)は、応答またはタイマーの期限が切れるまでそこで待機する必要があります。

以下のサンプルプログラムを作成しました。これは正しいアプローチではないと思います。より良いアプローチはありますか?このプログラムでは、interupt メソッドが呼び出されるタイミングがわかりません。

public class MethodTimeout implements Runnable{

/**
 * @param args
 */

public Thread t1 = null;
public int threadnum = 0;
public static void main(String[] args) {


    for (int i=0; i<3; i++){
        MethodTimeout mt  =new MethodTimeout();
        Thread t = new Thread(mt,"thread "+(i+1));
        mt.t1 = t;
        mt.threadnum = (i+1); 
        t.start();
    }

    System.out.println("stmt after execution");
}

public Object testTimeout(){
    long startTime = System.currentTimeMillis();
    try {

        System.out.println("in side method start "+t1.getName()+" start time"+startTime);

        Thread.sleep(5000);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    long endtime = System.currentTimeMillis();
    System.out.println("in side method end "+t1.getName()+" total time"+(endtime-startTime) );
    return null;
}


@Override
public void run() {

    Thread timeout  = new Thread (){
        public void run() {
            testTimeout();
        };
    };
    timeout.start();

    try {
        Thread.sleep(2000);
        timeout.interrupt();
        Thread.sleep(2000);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }       
    System.out.println(t1.getName() + " is ending");
}

}

4

2 に答える 2

1

これは、Callable を実装する必要があるように思えます。これはほんの一例です

 import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;

 public class Test {    
     public static void main(String[] args) throws Exception {
         ExecutorService service = Executors.newFixedThreadPool(2);
         Future<String> futureResult = service.submit(new MyCall());
             try{
                 String result = futureResult.get(20, TimeUnit.MILLISECONDS);
             } catch(TimeoutException timeout){
                  System.out.println("Timeout");
                  service.shutdownNow();
             }
   }

   static class MyCall implements Callable<String> {
        @Override
        public String call() throws Exception {
             try{
                  //Simulate some corba work
                  Thread.sleep(1000);
             }catch(InterruptedException e){
                  Thread.currentThread().interrupt();
                  System.out.println("Shutting down the task!");
             }
                 return "The result";
        }
    }
} 
于 2013-04-25T13:51:52.077 に答える
0

@Eugene の回答に 1 つの小さな変更を加えることもできます。つまり、それ自体で を呼び出す代わりにshutdownNow()ExecutorServiceタイムアウトにcancel(true)なったを呼び出すことができます。futureResultコード スニペットは次のとおりです。

public class Test {    
     public static void main(String[] args) throws Exception {
         ExecutorService service = Executors.newFixedThreadPool(2);
         Future<String> futureResult = service.submit(new MyCall());
             try{
                 String result = futureResult.get(20, TimeUnit.MILLISECONDS);
             } catch(TimeoutException timeout){
                  System.out.println("Timeout");
             } finally {
                  futureResult.cancel(true);
             }
   }

これは、タイムアウトしたスレッドのみがキャンセルされるようにするためです。現在shutdownNow()実行中のタスクを停止しようとするだけでなく、待機中のタスクが開始されないようにします。

于 2013-05-09T05:50:57.297 に答える