Path: csiph.com!news.mixmin.net!newsreader4.netcologne.de!news.netcologne.de!.POSTED.xdsl-84-44-179-215.netcologne.de!not-for-mail From: Patrick Roemer Newsgroups: de.comp.lang.java Subject: =?UTF-8?Q?Re:_GUI-Update_=c3=bcber_Swing-EDT?= Date: Sat, 16 Jul 2016 16:42:06 +0200 Organization: news.netcologne.de Distribution: world Message-ID: References: Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Injection-Date: Sat, 16 Jul 2016 14:42:06 +0000 (UTC) Injection-Info: newsreader4.netcologne.de; posting-host="xdsl-84-44-179-215.netcologne.de:84.44.179.215"; logging-data="9267"; mail-complaints-to="abuse@netcologne.de" User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.24) Gecko/20100411 Thunderbird/2.0.0.24 Mnenhy/0.7.6.0 In-Reply-To: Xref: csiph.com de.comp.lang.java:13001 Responding to Christian H. Kuhn: > Genau. getName() ist in meiner Anwendung unkritisch, weil Namen von > GUI-Komponenten nur im Konstruktor gesetzt und nie mehr verändert > werden, da entstehen keine Konflikte, solange nicht lesend auf ein noch > nicht fertig konstruiertes Objekt zugegriffen wird. Ich hoffe, dass die > VM sowas verhindert und ein Objekt erst da ist, wenn der Konstruktor > fertig ausgeführt ist? Wenn es keine happens-before-Beziehung gibt: Nein. Beispiel: "The most obvious reason is that the writes which initialize instance and the write to the instance field can be reordered by the compiler or the cache, which would have the effect of returning what appears to be a partially constructed Something. The result would be that we read an uninitialized object." https://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html#dcl > StringBuilder nameBuilder = new StringBuilder(); > try { > SwingUtilities.invokeAndWait(new Runnable() { > > @Override > public void run() { > _parent.getName(); // das geht > name = _parent.getName(); // das geht nicht > test.setObject(_parent.getName()); // das geht > staticName = _parent.getName(); // das geht > nameBuilder.append(_parent.getName()); // das geht > } > }); Die letzten drei gehen alle nicht, weil wieder nicht garantiert ist, dass der main-Thread die Resultate der im EDT ausgeführten Aktion je zu sehen bekommt. (Schlimmstenfalls bekommt er sie nur teilweise zu sehen.) public static T fromEDT(Supplier block) throws InterruptedException { final AtomicReference ret = new AtomicReference<>(); try { SwingUtilities.invokeAndWait(() -> ret.set(block.get())); } catch (InvocationTargetException exc) { Throwable cause = exc.getCause(); if(cause instanceof Error) { throw (Error)cause; } if(cause instanceof RuntimeException) { throw (RuntimeException)cause; } // shouldn't happen - no checked exceptions from Supplier/Runnable throw new RuntimeException(cause); } return ret.get(); } String name = SwingHelper.fromEDT(() -> _parent.getName()); Viele Grüße, Patrick