Chris Hurst

Ranch Hand
+ Follow
since Oct 26, 2003
Merit badge: grant badges
For More
Cows and Likes
Cows
Total received
In last 30 days
0
Forums and Threads

Recent posts by Chris Hurst

Can you synchronize on null?



No its not an object, it just wouldn't work but I think the consensus was he needs to sync on the array.

(You'd expect it to null pointer though I did wonder if any newer java version could pick up the sync on local object is pointless and use escape analysis to make it a noop and the just do nothing with regard to the sync rather than null pointer ?)
This doesn't look like a good exercise.

Just looking at the specs if it runs forever isn't the result out of memory error as it seems to suggest you should loop forever (albeit the code posted doesn't loop). Am I miss reading this ? It would have been better if each thread was allowed say 500 adds each then you join and show the results. If someone asked me to do this as spec'ed I'd make so it was parameterized to do n iterations where infinite was a possible setting for n.

I'd have another attempt (using Greg's suggestion to sync on just infiList) and post again.
1) In your example you use System.out.prinltln every implementation I have seen synchronizes so your code is synchronized ( I appreciate that was not your point ).

2)

I don't want to perform synchronization if I don't have to. Accessing a volatile variable incurs half of the cost of a synchronized block.


There is no guarantee of cost to volatile or the synchronized keyword and indeed in extreme scenarios the JVM would be allowed to optimize them away to nothing (not here).

When talking about "synchronization" and performance you are interested in three things lack of potential compiler optimization, cache flushes (memory fences) and lock acquisition (often only the first is considered). The JVM authors have put a lot of effort into some excellent optimizations around all three, potential lock acquisition has many tricks to make it less expensive than you'ed think.

3) The atomic implementation may make use of available CAS (lockless) instructions and the JVM implementation could make use of the fact the actual hardware is more strongly ordered than the weak model Java describes for the code to be portable . Although a processor may/will have caches those caches can and often do communicate with each other (between CPUs) such that much stronger memory ordering is observed than you might expect (e.g. Intel x86 is quite strong). The Java memory model is more like the worst case scenario and would formerly be described as weak.

Short answer ... just use atomic you'll be fine ;-) there are a whole host of other gotchas around performance with even simple examples eg "false memory sharing" and even old garbage collection I've seen applications grind with too many (badly used) Atomics (GC) .. synchronization can/could be just a flag on a method signature its GC free (not in anyway a normal a reason to not use atomics obviously).
1) The code as is has a bug .. msgArrived should be AtomicBoolean or volatile or you may get odd results.

2) wait / notify is probably the simplest solution, your inner class (IDataHandler()) should synchronize on a common object and notify when setting the boolean. Then replace the sleep with synchronizing on the same object and a wait (careful with using 'this' for synchronization as new IDataHandler() is an inner class).
Line 24 is covering the possibility that the thread (sleep or tryAcquire) is woken by a rare event "a spurious wakeup" i.e. the thread aquire or sleep did not take 500ms before failing.

https://en.wikipedia.org/wiki/Spurious_wakeup

Also discussed here ... https://coderanch.com/t/234023/threads/java/spurious-wakeup

An example use case if in the OS for some reason it needed to adjust the clock it might use this so you were woke up and could adjust your algorithm i.e. you might be waiting 500ms because that's when your flight leaves in real time and this wakeup allows you to adjust for the fact your watch was effectively wrong when you slept. In reality this may never occur with your OS/VM and even if its possible you'd expect it to be very rare.

Normally I would expect the try/catch within the loop and I'm not sure why you need the Thread.Sleep as the acquire is timed.

You have used join but i think Jeanne asked to write without using join.



The question from aqas qaqz asks for the code for a solution specifically with join ...

Please can anyone propose a code that exactly meets the solution specifications



To ensure three threads execute you need to start the last one first e.g. T3 and then call join methods in reverse order e.g. T3 calls T2.join, and T2 calls T1.join, this ways T1 will finish first and T3 will finish last.

Generally on a OS you would have that report the total process memory and subtract the heap to get the difference.

If you have the equivalent of a core dump you can see what else there is.

You haven't said what version of Java your using if its pre 8 it might be worth looking at your PermGen usage.

If you have a of of threads their stacks can eat memory (you can adjust stack size from the command line).

In general read through the java command line options and you should find some options to give you a little more back depending on what your running on.
9 years ago
A core dump will have a lot of additional information outside the java heap and indeed a java process requires more memory than the heap e.g. thread stacks won't appear in your GC data. If you create a lot of threads they will consume a lot more OS visible memory than appears to be taken in the heap (configurable on the command line) for instance.

Why are you using core dumps ? It makes far more sense to obtain hprofs and use those for leak analysis (with your gc analysis), I usually only use core dumps as the results of crashes and then usually convert them to hprofs.

You need to define why you think you may have a leak ... e.g. process memory consumption growing or GC analysis.

9 years ago
Given a large number of data types you want to ensure the consumers are from a pool of worker threads that consumed the far larger number of queues of data types. A new entry would wake up a worker which would acquire the right to work the given queue. I've seen this pattern before and it had similar issues where a thread per queue was required.

If you wish to consider a more high performance solution I suggest you google the disrupter pattern which would use a circular buffer rather than a blocking queue as a for for instance .

A simple overview ...

Disrupter

there are a few implementations out there already that should support similar work flows to the one your after and at least one is open source from memory.
Your executing a prepared statement on a given db connection while the statement is executing on the database another thread wants to do a commit via what looks to be the same connection, your jdbc driver vendor has decided both operations can't happen at the same time on the same connection so one waits fro the other to complete (seems reasonable).

This seems to be more of an architecture \ database performance issue.
General

i) Turn on trace class loading from the java command line to see which classes are loaded.
ii) turn on gc logging and look at the results in gc viewer.
iii) Get a hprof using jmap or jcmd (in your jdk) and examine the results in visualvm (in your jdk) or EclipseMat (free). In Eclipse mat run the leak suspects report.


For performance always set Xmx to same value as Xms.

If you have a huge number of classes (and have to have) set -XX:PermSize also (same value as max) each resize of permgen will full GC, you should be able to see this in your GC logs.

After that you are really into tuning the collector but its very dependent on what collector you are using ;-)

Good Luck.
9 years ago
Basically it looks like your doing all the work on the one and only GUI thread. The way round it would be to move the sine wave drawing code onto its own thread / job which would periodically call update allowing user interations to get in.
I agree with Paul it's very confusing.

Looking at what you have shown us do you have something that unregisters the listener i.e. what stops the first worker being a listener for any subsequent send on a new worker which you seem to make . Should the add listener bit being in more of an init type method i.e. it looks like everytime you send you add a new listener.

I suspect you shouldn't have a SwingWorker at all, you would just register a listener (only one) at program startup ? send messages from the GUI (EDT) thread on button clicks (just call send no wait) and in the listener method (SerialDataListener callback) do a SwingUtilies.invokeLater to update your GUI on the EDT (GUI thread) eg change some text to say this was the reply I got or whatever.
Hi,

Looking at what your actually doing ...

I do much java GUI work at the moment but it doesn't look like your using SwingWorker correctly, it might be easier if you give us the output your seeing.

doInBackground is meant to do a long running task it actually just adds a listener and returns immediately, which would call done immediately, I would have thought ?
Presumably the listener will call you back but that presumably is on a different thread not the worker as such. I don't think you do want a SwingWorker for this ?