2017-02-11 6 views
0

ループ内に新しいRunnableを作成したいと思います。ただし、内部クラス内で変数を使用することはできません。間違った結果を生成するため、グローバル/インスタンス変数を使用することはできません。私のプログラムは、以下の簡略化されたコードのようになります。新しいパラメータでループ内に新しいスレッドを作成する

public class RunManager { 
    public void runManager(int delay, final Context context) { 
     for (int dim = 7; dim < 227; dim++) { 
      Runnable r = new Runnable() { 
       @Override 
       public void run() { 
        RandomKernels randomKernels = new RandomKernels(); 
        try { 
         randomKernels.foo(context, dim); 
        } catch (InterruptedException e) { 
         Log.e(tag, e.getMessage()); 
        } 
       } 
      }; 
      Thread cnnThread = new Thread(r); 
      cnnThread.start(); 
      try { 
       Thread.sleep(delay); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 
} 

エラーは次のとおりです。Variable 'dim' is accessed from within inner class, needs to be declared final.

+0

本当に220種類のスレッドを作成したいですか? – BMacedo

+0

@BMacedoあなたの迅速な対応に感謝します。はい、各スレッドは5 ms後に計算を終了します。私はハードウェアの特性を監視するために擬似ワークロードを実行しようとしています。 – MTMD

答えて

1

あなたの問題は、あなたが新しいスレッドから非最終変数にアクセスしようとしているです。新しいスレッドからアクセスされる変数をneにするには、finalとして宣言する必要があります。あなたのcasでdim intをサイズ1の最終的なint配列にコピーして、スレッドから配列にアクセスすることができます。

0

おそらく最もわかりやすい方法は、Runnableのコンストラクタを作成して、パラメータとしてintを受け取ることです。以下のような:

public class MyRunnable implements Runnable { 

    public MyRunnable(Context context, int dim) { 
     // save parameters as class variables 
    } 

    public void run() { 
     // do the work 
    } 
} 

そして、それを呼び出す:あなたは内部クラス内の値にアクセスできるようにしたい場合は

Runnable r = new MyRunnable(context, dim); 
new Thread(r).start(); 
0

あなたはfinal int[] dimを使用する必要があります。

public class RunManager { 

    public void runManager(int delay, final Context context) { 
     for (final int dim[] = {7}; dim[1] < 227; dim[1]++) { 
      Runnable r = new Runnable() { 
       @Override 
       public void run() { 
        RandomKernels randomKernels = new RandomKernels(); 
        try { 
         randomKernels.foo(context, dim[1]); 
        } catch (InterruptedException e) { 
         Log.e(tag, e.getMessage()); 
        } 
       } 
      }; 
      Thread cnnThread = new Thread(r); 
      cnnThread.start(); 
      try { 
       Thread.sleep(delay); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 
} 

オプション2 - 用途:

public class RunManager { 

    private int _dim; 

    public void runManager(int delay, final Context context) { 
     for (int dim = 7; dim < 227; dim++) { 
      _dim = dim; 
      Runnable r = new Runnable() { 
       @Override 
       public void run() { 
        RandomKernels randomKernels = new RandomKernels(); 
        try { 
         randomKernels.foo(context, _dim); 
        } catch (InterruptedException e) { 
         Log.e(tag, e.getMessage()); 
        } 
       } 
      }; 
      Thread cnnThread = new Thread(r); 
      cnnThread.start(); 
      try { 
       Thread.sleep(delay); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 
} 

オプション3 - 反復別の方法で、メソッド引数としてfinal int dimを追加:

private void createThreads(int delay, final Object context) { 
    for (int dim = 7; dim < 227; dim++) { 
     runManager(delay, context, dim); 
    } 
} 

public void runManager(int delay, final Context context, final int dim) { 
    Runnable r = new Runnable() { 
     @Override 
     public void run() { 
      RandomKernels randomKernels = new RandomKernels(); 
      try { 
       randomKernels.foo(context, dim); 
      } catch (InterruptedException e) { 
       Log.e(tag, e.getMessage()); 
      } 
     } 
    }; 
    Thread cnnThread = new Thread(r); 
    cnnThread.start(); 
    try { 
     Thread.sleep(delay); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 
} 

オプション4 - カスタム実行可能な使用。 @BMacedoの推奨に従ってクラスを実装することも、抽象クラスを作成して内部クラスにロジックを実装することもできます。

public class RunManager { 

    public void runManager(int delay, final Context context) { 
     for (int dim = 7; dim < 227; dim++) { 
      CustomRunnable r = new CustomRunnable() { 
       private int _dim; 

       @Override 
       public void run() { 
        RandomKernels randomKernels = new RandomKernels(); 
        try { 
         randomKernels.foo(context, _dim); 
        } catch (InterruptedException e) { 
         Log.e(tag, e.getMessage()); 
        } 
       } 

       public void setDim(int dim) { 
        _dim = dim; 
       } 
      }; 

      r.setDim(dim); 

      Thread cnnThread = new Thread(r); 
      cnnThread.start(); 
      try { 
       Thread.sleep(delay); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 

    abstract class CustomRunnable implements Runnable { 
     public abstract void setDim(int dim); 
    } 
} 
関連する問題