मेरे पास एकाधिक कार्यकर्ता धागे हैं, और एक जावाएफएक्स जीयूआई जो इन धागे में क्या हो रहा है पर रिपोर्ट कर रहा है।जावाएफएक्स में जटिल समेकन: एकाधिक कार्यकर्ता धागे से पर्यवेक्षण सूची और गुणों का उपयोग
धागे के बीच साझा बहुत सारे डेटा हैं और इसे देखने की आवश्यकता है। तो मैं JavaFX में डेटा को आसानी से दिखाने में सक्षम होने के लिए ऑब्जर्जेबललिस्ट और प्रॉपर्टी का उपयोग कर रहा हूं।
मैंने अपने आवेदन में क्या होता है इसके समान कुछ दिखाने के लिए एक छोटा सा उदाहरण ऐप बनाया है। इसमें 2 सूचियां हैं और कार्यकर्ता थ्रेड डेटा को एक सूची से दूसरे में ले जाता है। एक स्टेटस स्ट्रिंग को अद्यतित रखा जाता है। पूर्ण उदाहरण कोड http://codetidy.com/6569/ में पाया जा सकता है (इस कोड, दुर्घटना होगा बाद में देखें)
यहाँ साझा ObservableList के & गुण हैं:
private ObservableList<String> newItems;
private ObservableList<String> readyItems;
private StringProperty status;
यहां बताया गया है कि वे JavaFX में किया जाता है:
listViewA.setItems(processor.getNewItems());
listViewB.setItems(processor.getReadyItems());
statusLabel.textProperty().bind(processor.getStatus());
कार्यकर्ता धागा इन सूचियों और गुणों को अद्यतन करता है, लेकिन निश्चित रूप से, इसे जावाएफएक्स थ्रेड पर ऐसा करने की ज़रूरत है, और यही वह जगह है जहां चीजें बदसूरत हो जाती हैं।
Platform.runLater(new Runnable() {
@Override
public void run() {
synchronized (newItems) {
if (newItems.size() >= 5)
status.set("Overload");
else
status.set("OK");
}
}
});
कि के लिए ठीक है:
Runnable newItemAdder = new Runnable() {
@Override
public void run() {
while(true) {
synchronized (newItems) {
String newItem = checkForNewItem(); //slow
if (newItem != null) {
newItems.add(newItem);
newItems.notify();
}
if (newItems.size() >= 5)
status.set("Overload");
else
status.set("OK");
}
synchronized (readyItems) {
if (readyItems.size() > 10)
readyItems.remove(0);
}
try { Thread.sleep(200); } catch (InterruptedException e) { return; }
}
}
};
new Thread(newItemAdder).start();
Runnable worker = new Runnable() {
@Override
public void run() {
while(true) {
List<String> toProcess = new ArrayList<String>();
synchronized (newItems) {
if (newItems.isEmpty())
try { newItems.wait(); } catch (InterruptedException e) { return; }
toProcess.addAll(newItems);
}
for (String item : toProcess) {
String processedItem = processItem(item); //slow
synchronized (readyItems) {
readyItems.add(processedItem);
}
}
}
}
};
new Thread(worker).start();
जरुर, कुछ बातें Platform.runLater साथ हल करने के लिए आसान कर रहे हैं: यह अगर मैं JavaFX धागे पर अद्यतन करने के लिए नहीं था कोड होगा गुण/सूचियां जिन्हें मैं केवल कार्य में लिखता हूं, और केवल जावाएफएक्स जीयूआई में पढ़ता हूं। लेकिन इस उदाहरण में सूचियों के लिए यह बहुत जटिल हो जाता है, जिस पर आपको सिंक्रनाइज़ करने, पढ़ने और लिखने की आवश्यकता होती है। आपको बहुत सारे Platform.runLater जोड़ने की आवश्यकता है और आपको "runLater" कार्य समाप्त होने तक अवरुद्ध करने की आवश्यकता है। इसका परिणाम कोड को पढ़ने और लिखने के लिए बहुत जटिल और कठिन होता है (मैं इस उदाहरण को इस तरह से चलाने में कामयाब रहा हूं, देखें कि मेरा क्या मतलब है: http://codetidy.com/6570/)।
क्या मेरे उदाहरण को काम करने के कोई अन्य तरीके हैं? मैं किसी अन्य समाधान या आंशिक समाधान की सराहना करेंगे ...
आपने अपने कोड में क्या बदलाव किया है? क्या आप उन्हें दिखा सकते हैं?गहनेसा का आखिरी लिंक – AloneInTheDark
@AloneInTheDark पर काम नहीं करता है, लेकिन मुझे डर है कि मेरे पास मूल उदाहरण कोड नहीं है, न ही गहने द्वारा संशोधित संस्करण। मैंने समाधान के सारांश के साथ एक अतिरिक्त उत्तर पोस्ट किया है। अच्छी सामान्य सलाह के लिए –