-1

こんにちは私は実行するために入力数の操作を取り、操作ごとに異なるスレッドを実行するJavaアプリケーションを持っています:

//create operations to execute
Thread t[] = new Thread [n_operations];

//we create a Bank with N accounts
Bank mybank = new Bank(N);

//execute a separate thread per operation
for (int i = 0; i < n_operations; i++) {
    int id = i;
    Operation o = new Operation(mybank, id);
    t[i]= new Thread (o);
    t[i].start();
}
for (int i=0;i<N;i++){
    try{
        t[i].join();
        }catch(Exception e){;}
}

次に、銀行クラスが次のように定義されているアカウントで同時転送を実行する必要があります。

public class Bank {

    private static        Account[] accounts;
    final  int      MAX_balance  = 100000;
    int         MAX_accounts = 0;

    /* Create accounts of a bank */
    public Bank (int N) {

        accounts = new Account[N];
        MAX_accounts = N;

        for (int i = 0; i < N; i++)

            accounts[i] = new Account (i, 1000);

    }
    public int getN(){
        return MAX_accounts;
    }

    public synchronized int transfer(int from, int to, int amount) {


            synchronized (accounts[from]){
          synchronized (accounts[to]){

          if (accounts[from].balance () < amount) {

              try{
              System.out.println("Error during transfer: Not enough Money");
              }
              catch(Exception err){ 
                  return 1;
              }              
         }

         accounts[from].sub(amount);
         accounts[to].add(amount);
        }
    }

    return 0;
    }
}

プログラムが操作を実行するとき:

public class Operation implements Runnable {

    private Bank      b;
    int id;
    Random r;
    private final int  MAX_TRANSFERENCIAS = 1000;

        public Operation (Bank b, int id) {

            this.b = b;
            this.id = id;

    }

    public int syncronize(){
        return 1;       
    }

    public void run () { 


        r = new Random();
        if(b == null)
              throw new RuntimeException("b is null!");
            if(r == null)
              throw new RuntimeException("r is null!"); 
        int max = b.getN();
        //depend if there is a conflict or not

            b.transfer (id,r.nextInt(max),r.nextInt(100));

    }
}

次のような一連のエラーが表示されます。

        at Bank.transfer(Bank.java:28)         /* which is "synchronized (accounts[from]){" */

        at Operation.run(Operation.java:33)    /* which is "b.transfer 
(id,r.nextInt(max),r.nextInt(100));" */

        at java.lang.Thread.run(Unknown Source)
    java.lang.ArrayIndexOutOfBoundsException: 4714

同期は大丈夫だと思いますか?

助言がありますか?どうもありがとう


更新(私は自分自身に答えることができません)

メインループ(i..to n_operations)に概念エラーがあり、関数は「int id=i;」を渡しています。source_accountのパラメーターとして、n_operation番号は配列の最大値よりも大きいため、コンパイラーは合理的に次のように言います:ArrayIndexOutOfBoundsException。

私はマルチスレッドの専門家ではないので、最後の貢献として、同期が正しく行われているかどうかを確認してください。改めて感謝します。そして今朝、質問をひどく定式化して申し訳ありません。

4

2 に答える 2

3

Edit:

Now that we know that the following line is the source of the NPE:

b.transfer (id,r.nextInt(max),r.nextInt(100));

So most likely b or r is null. You should put a break point there and debug into it to see if they are. You could also use assert or logging to display the values. Remember also that id or max could also cause a NPE if either is an Integer that is null and gets auto-boxed.


This wouldn't cause your NPE but be careful that n_operations may not be == 100? You are starting n_operations threads but joining with 100 of them:

for (int i=0;i<100;i++){
    try {
        t[i].join();
    } catch(Exception e){;}
}

I always use the length of the array in these cases so you don't have a mismatch between what was allocated:

for (int i = 0; i < t.length; i++) {

Also, at the very least you should always log or print your exceptions. Catching and dropping exceptions often means you are hiding important debugging information.

    } catch(Exception e){ e.printStackTrace(); }
于 2012-03-06T15:44:29.013 に答える
1

One of the variables you are using in run() is null, but which one? Try adding the following to the beginning of Operation.run():

if(b == null)
  throw new RuntimeException("b is null!");
if(r == null)
  throw new RuntimeException("r is null!");

I presume that the lines you showed from run() include line 27. If not, please post the full source code for run().

于 2012-03-06T15:48:14.033 に答える