我想实现一个耗时的任务的异步返回。所以任务数据被插入Q中,并立即返回。一堆20个线程从该数据队列中获取任务。但是线程中的数据变为空,我不知道为什么。Java线程问题,我得到一个null,而执行一个异步任务
代码段的(唯一相关的代码部分)
定义
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!");
}
在开始添加新的任务交给了Q(addFirst
)
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()
。我在这里错过了什么。基本的东西。
我已经使用了LinkedList,因此在结构上它应该工作。链表包含我需要处理的数据。它拥有一个Object数组,因为我有超过1个数据元素。
编辑:再次
private static final int KEY = 0 ;
private static final int VALUE = 1 ;
private static final int SIZE = 2 ;
编辑: 这是我如何打电话arrayize
ReadWriteOperations.getInstance(this).arrayizeToCache(key,
new CacheData(subscription, SuperCache.NEVER_EXPIRE));
我CacheData对象
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 ;
}
}
答:我是在所有的初始化值。有点认为这将是一个更复杂的事情。而且这里的凌晨2点:)感谢@Gray。
您应该考虑对此使用'ExecutorService'。通过分配自己的线程,然后从作业队列中读取数据,实际上就是在重写它们。请参阅:http://docs.oracle.com/javase/tutorial/essential/concurrency/exinter.html – Gray
如果您不移至“ExecutorService”,则应将“cacheQ”队列切换为“BlockingQueue”它负责同步,通知/等待等。 – Gray
我将链接列表更改为ConcurrentLinked和LinkedBlockingQueue,两者都不起作用。同样的结果。此处还有其他事情。 – taxeeta