1

Webサービスのバックグラウンドスレッドロガーを実装する必要がある割り当てを行う必要があります。ロガーの場合、runメソッドとfutureオブジェクトを返すメソッドがあるスケルトンコードを取得しました。ログ先行書き込みを実装する必要があるアクティビティのログについては、ロガーの新しいスレッドを開始し、Webサービスで挿入/更新コマンドを実行するときに何かをログに記録するコマンドを送信します(Webサービスはキーを実装します)値マップへ)、しかし、メインスレッドにログスレッドがログを終了するのを待たせることができません。誰か提案はありますか?多分私は何か間違ったことをしていますか?

public class IndexImpl implements Index<KeyImpl,ValueListImpl>
{
    private Thread log_thread;
    private MyLogger log;

    /*
     * in out pair, the long refers to the initial memory address that our data
     * has been saved too, and the integer refers to the length of the data in the file 
     */

    private HashMap<KeyImpl,Pair<Long,Integer>> m;
    private long endAddr;

    public IndexImpl()
    {
        valSer = new ValueSerializerImpl();
        endAddr = 0;
        m = new HashMap<KeyImpl,Pair<Long,Integer>>();
        this.log= new MyLogger();
        this.log_thread= new Thread(log);
        log_thread.start();
    }

    public void insert(KeyImpl k, ValueListImpl v) throws KeyAlreadyPresentException, IOException {
        locker.WriteLock(k);
        try {
            if (m.containsKey(k)) {
                throw new KeyAlreadyPresentException(k);
            }
            else {
            //LOGGING
                Object[] array = new Object[3]; // Key, Old Value List, New Value List
                array[0]= k.toString(); //Key
                array[1]= null; // Old value list
                array[2]= v; // New value list

            LogRecord l = new LogRecord(MyKeyValueBaseLog.class, "insert", array);
            FutureLog<LogRecord> future = (FutureLog<LogRecord>) log.logRequest(l);
            System.out.println("Inserting a new key " + k.getKey());
            future.get();

            long tempEndAddr;
            byte[] temp = valSer.toByteArray(v);
            //we are using the ReentrantReadWriteLock implementation found in java
            write.lock();
            try{
                tempEndAddr = endAddr;

                endAddr += temp.length;
            }
            finally{
                write.unlock();
            }

            store.write(tempEndAddr, temp);
            m.put(k, new Pair<Long, Integer>(tempEndAddr,temp.length));

        }
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (ExecutionException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }       
    finally
    {
        locker.WriteUnlock(k);
    }
}

そして、ロガーのコードは次のとおりです。

public class MyLogger implements Logger {

private ArrayList<LogRecord> log = new ArrayList<LogRecord>(100);


public MyLogger()
{

}

@Override
public void run() {
    // TODO Auto-generated method stub
    System.out.println("This is the logger thread! " + Thread.currentThread());
}

@Override
public Future<?> logRequest(LogRecord record) {
    // TODO Auto-generated method stub
    this.log.add(record);
    System.out.println("Record added to log! operation: " + record.getMethodName() );
    FutureLog<LogRecord> future = new FutureLog();
    return future;

}

}

4

1 に答える 1

1

ロガースレッドが開始され、すぐに終了します

@Override
public void run() {
    // TODO Auto-generated method stub
    System.out.println("This is the logger thread! " + Thread.currentThread());
}

代わりに、このメソッドをループして、受信したログレコードを書き込む必要があります。BlockingQueueから読み取ることをお勧めします。メソッドlogRequest()は、このキューにログレコードを追加する必要があります。そうすれば、メソッドは(キューによって提供されるtake()run()メソッドを使用して)キューで待機し、各レコードがキューから削除されるときに各レコードを書き出すだけです。

これを止めることができる必要があります、そしておそらくスレッドを中断することはここでの解決策です。

上記のすべては、単に1つの実装の選択肢です。あなたが抱えている根本的な問題は、スレッドがほぼ瞬時に開始/停止することです。

于 2012-12-11T11:24:18.583 に答える