具有 Runnable 接口(interface)的 Java Future 对象

标签 java logging future

我必须做一个作业,我必须为 Web 服务实现一个后台线程记录器,对于记录器,我们有一些骨架代码,其中有一个 run 方法和一个返回 future 对象的方法。为了记录 Activity ,我们必须实现预写日志记录,我设法为记录器启动一个新线程,并在 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;

}

}

最佳答案

您的记录器线程已启动,将立即退出

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

相反,您需要在此方法中循环,在日志记录进入时写入日志记录。我也许建议从 BlockingQueue 读取。 ,并且 logRequest() 方法应该将日志记录添加到该队列中。这样,您的 run() 方法将只在队列上等待(使用队列提供的 take() 方法),并在将每条记录从队列中取出时写出该记录。

你需要能够阻止这个,也许 interrupting线程是这里的一个解决方案。

以上所有只是一种实现选择。您遇到的根本问题是您的线程几乎立即启动/停止。

关于具有 Runnable 接口(interface)的 Java Future 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13819272/

相关文章:

java - 什么是断言错误?在哪种情况下我应该从我自己的代码中抛出它?

java - Android 应用程序无法连接到服务器

ios - 现有软件可以远程使用应用程序中的 iOS 日志吗?

windows - 如何找出哪个用户以编程方式将打印命令发送到 windows/windows 服务器?

scala - Actor 的接收方法中的多个 Future 调用

c++ - C++11 中的异步/ future 数量

java - applicationcontext.xml 来自另一个 jar 的 spring 服务

android - 为什么以及何时应该使用 android Log 类?

java - 导致取消任务失败的其他原因是什么?

java - Spring 安全 : AnonymousAuthenticationToken vs UsernamePasswordAuthenticationToken