3 回答

TA貢獻1784條經(jīng)驗 獲得超2個贊
如何傳遞對象并通知線程?我們將緩存對象保存在 HashMap 中,并且 CacheService 線程需要將密鑰傳遞給 MDLService。那么我應該使用哪種模式?
在我看來,你有 1 個線程太多了。XML 讀取線程和 MDL 寫入是有意義的,但是僅將內容放入內存緩存的線程似乎太復雜了。如果 MDL 生成器需要使用 Guava 緩存,那么它應該“擁有”緩存并將內容粘貼到其中。
這樣就剩下 1 個輸入 SAX 處理器線程和一個輸出 MDL 生成器線程。好的。要連接兩者,我會使用BlockingQueue
類似的LinkedBlockingQueue
. 您可能希望也可能不希望對隊列設置大小限制,具體取決于讀取是否比寫入快以及您的工作中有多少記錄。
所以你的主線程將創(chuàng)建BlockingQueue
然后將它傳遞給輸入和輸出線程。SAX 輸入線程調用put()
隊列,MDL 輸出線程調用take()
將對象放入 Guava 緩存,然后生成 MDL。
希望這可以幫助。

TA貢獻1780條經(jīng)驗 獲得超4個贊
由于您使用的是 Guava Cache,因此您可以使用 Guava AsyncEventBus 在任務之間調度消息,并取消三個單獨的專用 ExecutorServices。

TA貢獻1874條經(jīng)驗 獲得超12個贊
這是上述情況的示例實現(xiàn)。請注意,即使沒有 Guava 緩存也可以實現(xiàn),正如其他一些回復的人所提到的那樣;盡管如此,我認為 Nirmalaya 要求它可能是有正當理由的。我可以想到的一個這樣的原因是將緩存溢出到存儲設備或數(shù)據(jù)庫,以節(jié)省運行時內存。
員工記錄.xml
<?xml version="1.0" encoding="UTF-8"?>
<Employees>
<Employee id="1">
<name>Thomas</name>
</Employee>
<Employee id="2">
<name>Lisa</name>
</Employee>
<Employee id="3">
<name>Ronald</name>
</Employee>
<Employee id="4">
<name>Erica</name>
</Employee>
</Employees>
Employee.java
package com.technoroy.examples.guava;
/**
* A value holder POJO implementation for Employee records
* @author Rahul R
*
*/
class Employee {
private Integer id = null;
private String name = null;
public Employee() {
super();
}
public Employee(Integer id, String name) {
super();
this.id = id;
this.name = name;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Employee [id=" + id + ", name=" + name + "]";
}
}
GuavaCacheProcessor.java
package com.technoroy.examples.guava;
import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
/**
* The primary executable class
*
* @author Rahul R
*
*/
public class GuavaCacheProcessor {
private final static BlockingQueue<Integer> notificationQueue = new LinkedBlockingQueue<>();
public static void main(String... arguments) {
Runnable xmlProcessor = new Runnable() {
public void run() {
parseDataFile();
}
};
Runnable mdlGenerator = new Runnable() {
public void run() {
try {
while (true) {
Integer id = notificationQueue.take();
Employee record = ApplicationCacheUtil.getRecord(id);
generateContent(record);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
};
ExecutorService executorService = Executors.newFixedThreadPool(2);
executorService.submit(xmlProcessor);
executorService.submit(mdlGenerator);
}
public static void generateContent(Employee employee) {
System.out.println(employee);
}
public static void parseDataFile() {
SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
InputStream dataInputStream = GuavaCacheProcessor.class.getResourceAsStream("employee-records.xml");
try {
SAXParser saxParser = saxParserFactory.newSAXParser();
saxParser.parse(dataInputStream, new DefaultHandler() {
private Employee employee = null;
private StringBuilder elementValue = null;
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes)
throws SAXException {
if (qName.equalsIgnoreCase("Employee")) {
employee = new Employee();
String id = attributes.getValue("id");
if (id.matches("-?\\d+(\\.\\d+)?")) {
employee.setId(Integer.valueOf(id));
}
}
elementValue = new StringBuilder();
}
@Override
public void characters(char ch[], int start, int length) throws SAXException {
if (elementValue != null) {
elementValue.append(new String(ch, start, length));
}
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
if (qName.equalsIgnoreCase("name")) {
if (employee != null && elementValue != null) {
employee.setName(elementValue.toString());
}
} else if (qName.equalsIgnoreCase("Employee")) {
ApplicationCacheUtil.putRecord(employee.getId(), employee);
try {
notificationQueue.put(employee.getId());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
elementValue = null;
}
});
} catch (ParserConfigurationException | SAXException | IOException e) {
e.printStackTrace();
}
}
}
/**
* The Cache utilities class, that initializes and returns a handle to the
* cache.
*
* @author Rahul R
*
*/
class ApplicationCacheUtil {
private static Cache<Integer, Employee> cache = CacheBuilder.newBuilder().build();
public static Cache<Integer, Employee> getCache() {
return cache;
}
public static void putRecord(Integer key, Employee value) {
cache.put(key, value);
}
public static Employee getRecord(Integer key) {
return cache.getIfPresent(key);
}
}
添加回答
舉報