Несколько независимых потоков < /li>
Потоки создают ресурсы < /li>
Другое поток нуждается в доступе к ресурсам < /li>
< /ul>
Решения: < /p>
/> Повторная проверка. В основном не хороший выбор. < /P>
Недостатки: < /p>
Занят < /li>
больше кода < /li>
. /> completablefuture.образное Xfuture, затем вызовите любой из его методов) < /li>
< /ul>
Недостатки: < /p>
также обнажает отмену /полные механизмы < /li>
< /ul>
< /li>
free lockes /semaphores etc /semaphores etc /semaphores /semaphores /semaphores /semapres /semaphores < /p> /> Преимущества: < /p>
Легко в использовании < /li>
может заблокировать доступ к отмене /завершению, но с гораздо большим кодом < /li>
< /ul>
disadvantages: < /p>
excecater hardling is execker li Реализации (сторона поставщика) для блокировки и неблокирующего доступа < /li>
Обработка исключений не просто /нужно гораздо больше кода < /li>
< /ul>
< /li>
< /ol>
Я ищу лучшую структуру дизайна (при условии, что базовая задача не может изменить все возможное). Решения /Примеры: < /p>
Один один с занятым ожиданием < /li>
Один с завершенным fulture < /code>, это можно легко адаптировать для использования блокировки, Semaphores и т. Д. последовательность?
Код: Выделить всё
public class WaitForResourcePattern1_BusyWaiting {
public static void main(final String... args) {
final MainGui mainGui = new MainGui();
// stupid concept, but for arguments sake
new Thread(() -> new ControlPanel(mainGui), "Map Controller").start();
}
static class MainGui {
private MapPanel mComponent;
public MainGui() {
new Thread(() -> initialize(), "Initializer").start();
}
private void initialize() {
simulateWorkTime(10); // we're ignoring Exception handling in the examples
mComponent = new MapPanel();
}
public MapPanel getComponent() {
return mComponent;
}
}
static class MapPanel {
private List mData;
public MapPanel() {
new Thread(() -> initialize(), "Initializer").start();
}
private void initialize() {
simulateWorkTime(5); // we're ignoring Exception handling in the examples
mData = Arrays.asList("Hans", "Peter", "Jockl");
}
public List getData() {
return mData;
}
}
static class ControlPanel {
private final MainGui mMainGui;
public ControlPanel(final MainGui pMainGui) {
mMainGui = pMainGui;
new Thread(() -> startControlling(), "Map Controller").start();
}
private void startControlling() {
waitForResources();
System.out.println("Now I can finally work...");
final List data = mMainGui.getComponent().getData();
System.out.println("Data is: " + data.size());
for (final String d : data) {
System.out.println("\t" + "d" + "\t" + d);
}
}
private void waitForResources() {
while (true) {
final boolean resourcesAvailable = areResourcesAvailable();
if (resourcesAvailable) break;
sleep(300); // wait 1/3 second for retry
}
}
private boolean areResourcesAvailable() {
System.out.println("WaitForResourcePattern1.ControlPanel.areResourcesAvailable() resource check");
System.out.println("GUI is available:" + "\t" + (mMainGui != null));
if (mMainGui == null) return false; // actually, NO check necessary, because is assigned before Thread started
final MapPanel map = mMainGui.getComponent();
System.out.println("MAP available:" + "\t\t" + (map != null));
if (map == null) return false; // check/wait necessary
final List data = map.getData();
System.out.println("DATA available:" + "\t\t" + (data != null));
if (data == null) return false; // check/wait necessary
return true;
}
}
static public void sleep(final long pMilliSeconds) {
try {
Thread.sleep((long) (Math.random() * pMilliSeconds));
} catch (final InterruptedException e) { /* ignore */ }
}
static public void simulateWorkTime(final int pMaxSeconds) {
sleep((long) (Math.random() * 1000 * pMaxSeconds));
}
}
< /code>
Пример 2: < /p>
public class WaitForResourcePattern2_CompletableFuture {
public static void main(final String... args) {
final MainGui mainGui = new MainGui();
// stupid concept, but for arguments sake
new Thread(() -> new ControlPanel(mainGui), "Map Controller").start();
}
static class MainGui {
private final CompletableFuture mComponentFuture = new CompletableFuture();
public MainGui() {
new Thread(() -> initialize(), "Initializer").start();
}
private void initialize() {
try {
simulateWorkTime(10);
mComponentFuture.complete(new MapPanel());
} catch (final Exception e) {
mComponentFuture.cancel(true);
}
}
public CompletableFuture getComponentFuture() {
return mComponentFuture;
}
}
static class MapPanel {
private final CompletableFuture mDataFuture = new CompletableFuture();
public MapPanel() {
new Thread(() -> initialize(), "Initializer").start();
}
private void initialize() {
try {
simulateWorkTime(2);
mDataFuture.complete(Arrays.asList("Hans", "Peter", "Jockl"));
} catch (final Exception e) {
mDataFuture.cancel(true);
}
}
public CompletableFuture getData() {
return mDataFuture;
}
}
static class ControlPanel {
private final MainGui mMainGui;
public ControlPanel(final MainGui pMainGui) {
mMainGui = pMainGui;
new Thread(() -> startControlling(), "Map Controller").start();
}
private void startControlling() {
try {
waitForResources();
System.out.println("Now I can finally work...");
final List data = mMainGui.getComponentFuture().get().getData().get(); // this looks wrong
System.out.println("Data is: " + data.size());
for (final String d : data) {
System.out.println("\t" + "d" + "\t" + d);
}
} catch (InterruptedException | ExecutionException | IllegalStateException e) {
System.err.println("Error while loading the data in the other component; Aborting.");
}
}
private void waitForResources() throws InterruptedException, ExecutionException, IllegalStateException {
System.out.println("WaitForResourcePattern2.ControlPanel.areResourcesAvailable() resource check");
final MapPanel panel = mMainGui.getComponentFuture().get();
final List data = panel.getData().get();
System.out.println("DATA available:" + "\t\t" + (data != null));
if (data == null) throw new IllegalStateException("No data available in other component.");
}
}
static public void sleep(final long pMilliSeconds) {
try {
Thread.sleep((long) (Math.random() * pMilliSeconds));
} catch (final InterruptedException e) { /* ignore */ }
}
static public void simulateWorkTime(final int pMaxSeconds) {
sleep((long) (Math.random() * 1000 * pMaxSeconds));
}
}
Подробнее здесь: https://stackoverflow.com/questions/797 ... -resources