Java线程问题,我在执行异步任务时得到null

时间:2013-07-22 19:46:13

标签: java multithreading

我正在尝试为耗时的任务实现异步返回。因此任务数据插入Q中,并立即返回。一堆20个线程从该数据队列中获取任务。但是线程中的数据变为空,我想知道为什么。

代码段(仅代码的相关部分)

定义

private static LinkedList<Object[]> cacheQ = new LinkedList<Object[]>();
private static ArrayList<Thread> cacheThreads = null;

一次初始化

if (cacheThreads == null) {
        cacheThreads = new ArrayList<Thread>();
        for (i = 0; i < 20; i++) {
            CacheThread cacheThread = readWriteOps.new CacheThread();
            Thread thread = new Thread(cacheThread);
            cacheThreads.add(i, thread);
            thread.start();
        }
        System.out.println("CAche Threads Started!");
    }

在开头(addFirst

向Q添加新任务
public void arrayizeToCache(String key, CacheData value) {
    synchronized (cacheThreads) {
        Object[] tuple = new Object[SIZE] ;
        tuple[KEY] = key ;
        tuple[VALUE] = value ;
----NOT NULL----log.debug("CacheThread arrayizeToCache k"+key+"v"+value) ;
        cacheQ.addFirst((Object[])tuple);
        cacheThreads.notify();
    }
}

线程的实际工作

public class CacheThread implements Runnable {
    @Override
    public void run() {
        System.out.println("CachedThread running!");
        CacheData cacheStore = null;
        while (true) {
            try {
                String key;
                synchronized (cacheThreads) {
                    if (cacheQ.isEmpty()) {
                        log.debug("Cache Q waiting");
                        cacheThreads.wait();
                    }
                    if (cacheQ.isEmpty()) {
                        log.error("Cache List empty nothing to cache");
                        continue;
                    }
                    Object[] cacheData = (Object[]) cacheQ.removeLast();
                    key = (String) cacheData[KEY] ;
                    cacheStore = (CacheData) cacheData[VALUE];
----- HERE -----
//More code, but irrelevant for this question. 
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            // log.debug(((Runnable) this).toString() +
            // "Server : flush SUCCESS");
        }
    }
}

-----HERE----- cacheStore.getValue()我的空格为private static final int KEY = 0 ; private static final int VALUE = 1 ; private static final int SIZE = 2 ; 。我在这里想念的是什么基本的东西。

我为Q使用了LinkedList,所以在结构上它应该可行。链表持有我需要处理的数据。它包含一个Object数组,因为我有多个数据元素。

编辑:

ReadWriteOperations.getInstance(this).arrayizeToCache(key,
            new CacheData(subscription, SuperCache.NEVER_EXPIRE));

再次编辑: 这就是我调用arrayize

的方式
public class CacheData {
private Object value ;
private Integer expiry = 0 ;
public CacheData(Object newValue) {
    value = newValue ;
}
public CacheData (Object newValue, Integer newExpiry) {
// THIS LINE WAS MISSING        value = newValue ;
    expiry = newExpiry ;
}
public Object getValue() {
    return value ;
}
public Integer getExpiry () {
    return expiry ;
}
}

我的CacheData对象

{{1}}

答案:我正在初始化价值。有点认为这将是一个更复杂的事情。这是凌晨2点:)感谢@Gray。

1 个答案:

答案 0 :(得分:1)

您的代码对我来说很好。我很想知道:

  • cacheStore的值在哪里更新?
  • 线程启动后是否更新?这可能是问题所在。
  • 如果是,则需要在synchronized (cacheThreads) {块内更新,以使更改对正在运行的线程可见。

以下是有关代码的其他评论:

  • 您正在分配自己的主题,然后为作业提供synchronized LinkedList。我鼓励你研究一下ExecutorService patterns这两个人。绝对推荐用于大多数线程任务。

  • 如果您没有转到ExecutorService,则应将cacheQ队列切换为BlockingQueue,以处理synchronized,{ {1}} / notify()等等。