Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Max Facetime
Apr 18, 2009

Broken pipe means that someone has unceremoniously dumped the socket connection. It could be some router/firewall along the connection or the OS when it cleans up open sockets from a process that was terminated.

I'm not sure if it's even possible to generate a broken pipe error condition in 100% Pure Java.

Adbot
ADBOT LOVES YOU

covener
Jan 10, 2004

You know, for kids!

fart factory posted:

I'm having an issue with a broken pipe exception within a java program. The exception occurs when the server recieves an unusually long xml message. I've read that this can cause the broken pipe because the writing thread has already finished by the time the reading thread has processed the message and sent the response. Some sort of countdown latch has been proposed, but the thread that is writing the data to the server is part of a different project. Is there any other way to ensure that the thread will stay running until all the data has been read/response has been sent?

maybe "lingering close" is the phrase that pays here.

Internet Janitor
May 17, 2008

"That isn't the appropriate trash receptacle."
I've been tinkering with a simple Forth compiler in Java, and while emitting bytecode for my own simple VM is thrilling and educational, I thought it would be even more fun to see if I could generate .class files that the JVM itself can execute. For the moment, let's ignore interoperability with Java and other JVM languages, as this is intended as just a toy implementation.

Forth is a stack-oriented language built out of "words". A word is essentially a very lightweight method wherein a global data stack is used for passing arguments and returning results rather than making this explicit through signatures. Most words are little more than a sequence of literal values to push onto the stack and subroutine calls to other words, terminated in a return. It's easy to see how this sort of language is very simple to compile.

JVM bytecode is itself stack-oriented, and most of the primitives I'd need already exist. I need a very different calling convention from what Java uses, but it looked like I might be able to use the jsr and ret bytecodes (intended for implementing try...catch) along with a return stack I maintain myself in a local to compile all my forth words into a single Java method.

I got as far as writing most of the code to emit method entries and the constant pool for a .class when I discovered that the JVM class verifier will rain on this parade:

killjoys at Sun posted:

If an instruction can be executed along several different execution paths, the operand stack must have the same depth prior to the execution of the instruction, regardless of the path taken.

Now, I understand I'm trying to fit a square peg in a round hole here. The JVM is not meant to be programmed in this way, and even if my approach worked it would probably tie the JIT in knots. Still, I want to believe there's a cleaner way to do this than making each word a separate void method with no arguments and maintaining the data and return stacks as private fields. Any thoughts? Should I just shoot for an easier target like LLVM?

Paolomania
Apr 26, 2006

Are you intending to have dynamic word dictionaries? If so, you will need to maintain alot of extra structures yourself behind the scenes. Also, I imaging having more than one value on the return stack will be problematic. Also, I am almost certain that Forth has alot of symbols that are valid word names that Java would barf on (such as '*') even if you use something like dynamically adding methods glommed onto one main dicitonary object and the new invokedynamic opcode to get at them. IMO you will have much more success implementing a Forth interpreter.

Paolomania fucked around with this message at 06:56 on Jan 8, 2011

Internet Janitor
May 17, 2008

"That isn't the appropriate trash receptacle."
As it stands now, I'm implementing a subset of a proper Forth system, and I don't have a dynamic dictionary. Word names that are not valid Java identifiers are indeed a serious problem with the workaround I mentioned earlier. If I go with a Forth interpreter I'm basically back where I started with a simple custom VM of my own design, whether it sits on top of the JVM or bare metal.

Paolomania
Apr 26, 2006

Another basic problem is that Java stack frames are fairly isolated from eachother. From http://java.sun.com/docs/books/jvms/second_edition/html/Overview.doc.html section 3.5.2 :

quote:

Because the Java virtual machine stack is never manipulated directly except to push and pop frames, frames may be heap allocated. The memory for a Java virtual machine stack does not need to be contiguous.

So you never really have the option of leaving a "return stack" on the stack because as soon as you return, your local stack frame is gone and only the declared return type is left on the top of the calling stack frame. Perhaps you could package the return values as some Object array of known size which you then explode onto the calling stack after you return.

Internet Janitor
May 17, 2008

"That isn't the appropriate trash receptacle."
Yeah, which is why I wanted to try to fit everything into a single method, and therefore a single, shared stack frame. If I'm in a single method, I can also use the constant and local pools extensively for the "global" variables, constants and arrays used in Forth which keeps the code I need to emit very simple. If my words are each a separate method I have to do something like you describe to package/unpackage return values everywhere or use private fields of the enclosing class:

code:
: increment 1 + ;
: quux 2 increment ;
becomes something like:
code:
class Foo {
  private final Stack<Integer> data = new Stack<Integer>();

  public void increment() {
    data.push(1);
    data.push(data.pop() + data.pop());
  }

  public void quux() {
    data.push(2);
    increment();
  }
}

Scaevolus
Apr 16, 2007

Internet Janitor posted:

Yeah, which is why I wanted to try to fit everything into a single method, and therefore a single, shared stack frame. If I'm in a single method, I can also use the constant and local pools extensively for the "global" variables, constants and arrays used in Forth which keeps the code I need to emit very simple. If my words are each a separate method I have to do something like you describe to package/unpackage return values everywhere or use private fields of the enclosing class:
These notes on implementing Forth on the JVM may be useful: http://www.mistybeach.com/articles/ForthDimensionsArticle.html

Two Percent
Aug 26, 2005
Okay, is there a component of the JDK that could name me which JARs (and possibly other files) a particular JVM program accesses? Obviously it's not my software and I don't have the source code, I'd just like to know exactly what files it needs in order to operate.

A second way to find this information would be, I guess, to debug. I'm a bit familiar with Windows exe debugging and fiddling with RAM memory to change or even extract data, but Java doesn't really allow for debugging without the source code as far as I know, does it?

Malloc Voidstar
May 7, 2007

Fuck the cowboys. Unf. Fuck em hard.

Two Percent posted:

A second way to find this information would be, I guess, to debug. I'm a bit familiar with Windows exe debugging and fiddling with RAM memory to change or even extract data, but Java doesn't really allow for debugging without the source code as far as I know, does it?
http://java.decompiler.free.fr/

Turns Java bytecode (what you have) into Java source code. Not perfect, but pretty drat good.

Parantumaton
Jan 29, 2009


The OnLy ThInG
i LoVe MoRe
ThAn ChUgGiNg SeMeN
iS gEtTiNg PaId To Be A
sOcIaL MeDiA sHiLl
FoR mIcRoSoFt
AnD nOkIa

Aleksei Vasiliev posted:

but pretty drat good.

I'll provide the footnote:
If the software you're decompiling has been ran through a bytecode obfuscator such as ProGuard, it is possible that the decompiled version cannot be compiled again and is missing pieces of original code. This is because the bytecode specification allows for things which Java doesn't and as such aren't decompilable back to Java. This also means that you can't really judge on the efficiency of the code while wieving a decompiled version of it.

fart factory
Sep 28, 2006

SHREK IS COOL

I am in posted:

Broken pipe means that someone has unceremoniously dumped the socket connection. It could be some router/firewall along the connection or the OS when it cleans up open sockets from a process that was terminated.

I'm not sure if it's even possible to generate a broken pipe error condition in 100% Pure Java.

Yeah, turns out the other system wasn't waiting for a response, so by the time our system had finished processing the longer xml message, the client connection had been closed. Fixed though. Thanks for the help.

Thermopyle
Jul 1, 2003

...the stupid are cocksure while the intelligent are full of doubt. —Bertrand Russell

code:
	public void parseUrl(String url) {
		try {
			this.doc = Jsoup.connect(url).get();
		} catch (IOException e) {
			try {
				Thread.sleep(10*1000);
			} catch (InterruptedException e1) {
				e1.printStackTrace();
			}
			try {
				this.doc = Jsoup.connect(url).get();
			} catch (IOException e1) {
				System.out.printf("Error fetching %s", url);
				e1.printStackTrace();
			}
		}
	}
This looks and feels dumb.

What's a better way to try to fetch the url and if it fails wait 10 seconds and try again before REALLY failing?

epswing
Nov 4, 2003

Soiled Meat

Thermopyle posted:

What's a better way to try to fetch the url and if it fails wait 10 seconds and try again before REALLY failing?

Something like

code:
    public void parseUrl(String url) {
        
        int retryCount = 1;
        final int retryDelay = 10; // in seconds
        
        do {
            try {
                
                this.doc = Jsoup.connect(url).get();
                
            } catch (IOException e) {
                
                System.out.println("Error connecting, " + retryCount  + " retries left.");
                
                // don't wait if we're not going to retry anyways
                if (retryCount > 0) {
                    System.out.println("Trying again in " + retryDelay + " seconds.");
                    Thread.sleep(retryDelay * 1000);
                }
            }
        }
        while (retryCount-- > 0);
    }

epswing fucked around with this message at 23:28 on Jan 12, 2011

Your Computer
Oct 3, 2008




Grimey Drawer
I'm working on a particle system for fun, but I'm very new to java GUI programming.
I started with a JOGL setup for NetBeans with a GLCanvas (which is initiated as such):
code:
private GLCanvas canvas;

canvas.addGLEventListener(gl);
animator = new Animator(canvas);
animator.start();
Now, I don't know even know what an Animator is, but from what I can get the rendering happens on the awt event queue dispatch thread (or something like that). Now, the engine itself I start with a new thread, and do (simplified):
code:
while(true) {
    particleEngine.onUpdate();
    Thread.sleep(50);
}
the onUpdate() method calculates a few things that are necessary and then calls on GLRenderer's onUpdate() (a method I made myself).
Here's where the trouble starts. The GLRenderer is where the rendering happens (and some more things because I was having trouble with this), but I keep eventually getting a ConcurrentModificationException. This exception is coming from the ArrayList I use for storing the particles. At first, this was because I was trying to add, remove, draw and update from the same ArrayList in two different threads but now I have something that works MOST of the time, using different ArrayLists for adding, removing and rendering. Eventually, I always get a ConcurrentModificationException though.

I understand that I need to learn some concurrency, but I've never worked with threads directly before so this is confusing :(

A (simplified) example of what I'm doing right now in the GLRenderer:
code:
public void display() {
    for(int i = 0; i < displayList.size(); i++) {
        displayList.get(i).onRender(gl);
        if(displayList.get(i).isFinished()) {
            removeList.add(displayList.get(i));
        }else {
            displayList.get(i).onUpdate();
        }
    }
}

public void onUpdate() {
    displayList.removeAll(removeList);
    removeList.clear();
            
    displayList.addAll(addList);
    addList.clear();
}
A (possibly uninteresting) fact is that I can't do
code:
for(Particle p : displayList) {
    p.onRender(gl);
    if(p.isFinished()) {
        removeList.add(p);
    }else {
        p.onUpdate();
    }
}
or it'll error after a few milliseconds. Why this is, I don't quite understand. I guess it uses a different method of looking each particle up?


TL/DR: How do I add, remove, iterate through and render from an ArrayList across several threads?

Thermopyle
Jul 1, 2003

...the stupid are cocksure while the intelligent are full of doubt. —Bertrand Russell

Your Computer posted:

TL/DR: How do I add, remove, iterate through and render from an ArrayList across several threads?

I'm really new to the Java language, but it's my understanding that ArrayLists aren't thread-safe.

Try using a BlockingQueue of some sort?

Your Computer
Oct 3, 2008




Grimey Drawer
I just tried adding
code:
synchronized(displayList) {
}
on each block of code. It seems to be working now, just slower? Is this even the right way to do something like this?

Kilson
Jan 16, 2003

I EAT LITTLE CHILDREN FOR BREAKFAST !!11!!1!!!!111!

Thermopyle posted:

I'm really new to the Java language, but it's my understanding that ArrayLists aren't thread-safe.

I think you can wrap an ArrayList with Collections.synchronizedList to make it thread-safe. Not sure what the performance characteristics are, or even the exact behavior.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
Using an explicit synchronized around pieces of code that internally need to see a consistent view of the list is the right solution. Collections.synchronizedList will not work; it wraps its argument in a new List object which does synchronization on individual operations, but what you need is synchronization over an entire iteration, which means that fine-grained synchronization is not good enough (it rarely is).

The higher-performance way to do this is to make read-only data structures which do not require synchronization. Your simulation loop creates or modifies something that you're sure that the UI thread isn't currently trying to render; when it's done, you write the new reference into a volatile variable. The UI thread just reads out of that variable when it needs to render. The challenge here is to not do so much reallocation that the GC is constantly firing.

Flobbster
Feb 17, 2005

"Cadet Kirk, after the way you cheated on the Kobayashi Maru test I oughta punch you in tha face!"

Kilson posted:

I think you can wrap an ArrayList with Collections.synchronizedList to make it thread-safe. Not sure what the performance characteristics are, or even the exact behavior.

Since Collections.synchronizedList returns a list that presumably has the synchronized modifier on each method (or synchronized(this) wrapping the body), it would be obtaining and releasing the monitor on each method call, so you could still run into concurrency issues if you needed to perform multiple operations on the list but have it appear atomic for the sake of consistency.

In most cases I think it's better to explicitly synchronize the list access code instead of relying on Collections.synchronizedList.

edit: beaten

fletcher
Jun 27, 2003

ken park is my favorite movie

Cybernetic Crumb
While we're on the topic of concurrency, I discovered ExecutorService the other day and it is awesome. Made it a piece of cake to make my little utility app multi-threaded, and now it runs 8x faster.

Janitor Prime
Jan 22, 2004

PC LOAD LETTER

What da fuck does that mean

Fun Shoe

fletcher posted:

While we're on the topic of concurrency, I discovered ExecutorService the other day and it is awesome. Made it a piece of cake to make my little utility app multi-threaded, and now it runs 8x faster.

Yes it is awesome, I used it to test and reproduce a race condition in another part of my code.

Thermopyle
Jul 1, 2003

...the stupid are cocksure while the intelligent are full of doubt. —Bertrand Russell

As mentioned, I'm pretty new to Java, so I don't know if this is a widely known library, but lambdaj is pretty awesome.

Brings some of my favorite python features to Java.

quote:

lambdaj is designed to easily manipulate collections. Its features are intended to filter, convert, index and aggregate the items of a collection without explicitly iterate on it. Moreover the lambdaj API are designed to be easily concatenated in order to jointly use two or more features in a single statement. All those features are provided as static methods in the class Lambda, so the best way to use them is just to add the following import:

code:
List<Person> oldFriends = filter(having(on(Person.class).getAge(), greaterThan(30)), meAndMyFriends);

Malloc Voidstar
May 7, 2007

Fuck the cowboys. Unf. Fuck em hard.
Where can I find a good tutorial on concurrency?

I have some code that 1) takes a noticeable amount of time, and 2) should be easy to multithread (lots of tasks that don't depend on any previous computation)

But I don't know anything about concurrency and don't know where to learn it.

baquerd
Jul 2, 2007

by FactsAreUseless

Aleksei Vasiliev posted:

Where can I find a good tutorial on concurrency?

I have some code that 1) takes a noticeable amount of time, and 2) should be easy to multithread (lots of tasks that don't depend on any previous computation)

But I don't know anything about concurrency and don't know where to learn it.

I've had multiple graduate courses on concurrency, it's not a brief topic when you're talking about optimization. There are a ton of tutorials only a google away though that will show you how to make multiple threads. From there, assuming you need to wait for the individual results from your threads to be available, look at CountDownLatch and java.util.concurrent in general.

http://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/CountDownLatch.html
http://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/package-summary.html

Note these packages were added to significantly in 1.6

Malloc Voidstar
May 7, 2007

Fuck the cowboys. Unf. Fuck em hard.

baquerd posted:

I've had multiple graduate courses on concurrency, it's not a brief topic when you're talking about optimization.
Okay then change my question to "This code is really gross, where do I learn to make it less ew?"
(code-highlighting pastebin)
code:
 // Way up above constructor:
private final ExecutorService executor = Executors.newFixedThreadPool(4);

//calling statement:
byte[][] field1 = genRawField(splitFieldImage(fraps));

//normal code:
protected byte[][] genRawField(final BufferedImage[][] ss) {
	final byte[][] raw = new byte[ss.length][ss[0].length];
	for (int i = 0; i < ss.length; i++) {
		for (int k = 0; k < ss[0].length; k++) {
			raw[i][k] = closestGemType(averageInner(ss[i][k]));
		}
	}
	return raw;
} // every iteration step is a single operation unaffected by any other computation



// really ugly hack-job multithreaded code:
protected byte[][] genRawFieldM(final BufferedImage[][] ss) {
	final byte[][] raw = new byte[ss.length][ss[0].length];
	final List<Future<?>> futureList = new LinkedList<Future<?>>();
	for (int i = 0; i < ss.length; i++) {
		for (int k = 0; k < ss[0].length; k++) {
			// raw[i][k] = closestGemType(averageInner(ss[i][k]));
			final int y = i, x = k;
			final Future<?> f = executor.submit(new Runnable() {
				@Override
				public void run() {
					setsomething(raw, ss[y][x], y, x);
				}
			});
			futureList.add(f);
		}
	}
	for (final Future<?> f : futureList) {
		try {
			f.get(); // Waits until operation completed
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (ExecutionException e) {
			e.printStackTrace();
		}
	}
	return raw;
}

private void setsomething(final byte[][] raw, final BufferedImage piece, final int y, final int x) {
	raw[y][x] = closestGemType(averageInner(piece));
}
// gross!

It works (I have a method running both and checking if the output differs) but ewwwww.

The tutorials I've found on ExecutorServices/Futures tend to be vague and really love to just print lines instead of do something useful.

(I wrote this code after I asked my question, I'm not a dick)

baquerd
Jul 2, 2007

by FactsAreUseless

Aleksei Vasiliev posted:

It works (I have a method running both and checking if the output differs) but ewwwww.

The tutorials I've found on ExecutorServices/Futures tend to be vague and really love to just print lines instead of do something useful.

(I wrote this code after I asked my question, I'm not a dick)

Oh god, scrap this. I guess first is to question your usage of threading at all. Unless closestGemType() or averageInner() is computationally expensive, there's no purpose here. Next I would look at a dynamic programming solution from the sounds of the functions but they're not shown so I can't say for sure.

Read the sample usage on CountDownLatch and build your model around a worker/dispatched class instead of an anonymous inner class yucky thread mess. That alone will improve how this looks drastically.

Malloc Voidstar
May 7, 2007

Fuck the cowboys. Unf. Fuck em hard.

baquerd posted:

Oh god, scrap this.
Well, yeah, I went from nothing to working-but-gross in 15 minutes.

baquerd posted:

I guess first is to question your usage of threading at all. Unless closestGemType() or averageInner() is computationally expensive, there's no purpose here.
They aren't, really, but I have a very-similar-but-somewhat-harder method in my code that is somewhat expensive (and can/will become considerably more expensive due to improvements). I'd rather know what I'm doing before working on multithreading it.

baquerd posted:

Next I would look at a dynamic programming solution from the sounds of the functions but they're not shown so I can't say for sure.

Read the sample usage on CountDownLatch and build your model around a worker/dispatched class instead of an anonymous inner class yucky thread mess. That alone will improve how this looks drastically.
What do you mean by "dynamic programming solution"?

And I'll go look into CountDownLatch.

edit: And I used an anonymous inner class because I can't use a separate class, and implementing Runnable on the class itself for only part of its logic doesn't make sense (to me)

Malloc Voidstar fucked around with this message at 13:32 on Jan 14, 2011

baquerd
Jul 2, 2007

by FactsAreUseless

Aleksei Vasiliev posted:

What do you mean by "dynamic programming solution"?

http://en.wikipedia.org/wiki/Dynamic_programming

quote:

edit: And I used an anonymous inner class because I can't use a separate class, and implementing Runnable on the class itself for only part of its logic doesn't make sense (to me)

Why can't you use a separate class? If you really need it to be an inner class so you don't have to refactor everything, alright, but they're generally bad ideas in concurrent programming because you turn all of the enclosing class's variables into non thread-safe concurrency bombs (which may or may not be OK depending on those functions I mentioned)

Malloc Voidstar
May 7, 2007

Fuck the cowboys. Unf. Fuck em hard.

baquerd posted:

http://en.wikipedia.org/wiki/Dynamic_programming

Why can't you use a separate class? If you really need it to be an inner class so you don't have to refactor everything, alright, but they're generally bad ideas in concurrent programming because you turn all of the enclosing class's variables into non thread-safe concurrency bombs (which may or may not be OK depending on those functions I mentioned)
splitFieldImage(BufferedImage): Takes in a image (a screenshot), splits it into a 2D array of BufferedImages based on things that aren't important here
averageInner(BufferedImage): Averages the colors of a certain part of given image
closestGemType(Color): Returns a Gem of the closest color given
Seems to split the problem into subproblems to me. I'm building a 2D array of Gems, from a 2D array of BufferedImages.

None of this is expensive, but I need to refactor aforementioned expensive method due to it relying on non-obvious behavior that makes it hard to multithread, and I decided to learn basic concurrency first.

As for a separate class, I'm working on an abstract class. If a method needs to be overridden (and it almost certainly will), I'd rather it not be in a separate class. And implementing in the main class seems dumb since I could then only multithread one part of the code, and nothing else.

tef
May 30, 2004

-> some l-system crap ->

Aleksei Vasiliev posted:

Where can I find a good tutorial on concurrency?

I have some code that 1) takes a noticeable amount of time, and 2) should be easy to multithread (lots of tasks that don't depend on any previous computation)

But I don't know anything about concurrency and don't know where to learn it.

I think you mean 'I have a parallel problem'

concurrency is more about multi-agent stuff/actors style problems
and parallelism is more about dataflow/pipeline problems

you might try an algorithmic skeleton library to make your life easier

http://skandium.niclabs.cl/documentation/

baquerd
Jul 2, 2007

by FactsAreUseless

Aleksei Vasiliev posted:

splitFieldImage(BufferedImage): Takes in a image (a screenshot), splits it into a 2D array of BufferedImages based on things that aren't important here
averageInner(BufferedImage): Averages the colors of a certain part of given image
closestGemType(Color): Returns a Gem of the closest color given
Seems to split the problem into subproblems to me. I'm building a 2D array of Gems, from a 2D array of BufferedImages.
The one that sticks out the most to me is the averageInner() function as image blurring is a classic dynamic programming problem, but it sounds like you're computing a literal RGB average.

quote:

As for a separate class, I'm working on an abstract class. If a method needs to be overridden (and it almost certainly will), I'd rather it not be in a separate class. And implementing in the main class seems dumb since I could then only multithread one part of the code, and nothing else.

Static nested class, but these are all implementation details that shouldn't be in an abstract class in the first place!

Malloc Voidstar
May 7, 2007

Fuck the cowboys. Unf. Fuck em hard.

baquerd posted:

Static nested class, but these are all implementation details that shouldn't be in an abstract class in the first place!
It should in my case. I'm writing bots for Bejeweled-type games. So far two games more-or-less written, with more I'm going to work on.

No point in rewriting all the code when there are only small differences between games.

baquerd
Jul 2, 2007

by FactsAreUseless

Aleksei Vasiliev posted:

It should in my case. I'm writing bots for Bejeweled-type games. So far two games more-or-less written, with more I'm going to work on.

No point in rewriting all the code when there are only small differences between games.

Thinking about this a bit more, I think these particular methods are utilities that may be better moved to a package private static library class, but it's your design ultimately.

On the base assumption that threading is better here, I'd run some tests... creating threads and waiting for them to finish isn't trivial computationally either.

trex eaterofcadrs
Jun 17, 2005
My lack of understanding is only exceeded by my lack of concern.

Aleksei Vasiliev posted:

Where can I find a good tutorial on concurrency?

I have some code that 1) takes a noticeable amount of time, and 2) should be easy to multithread (lots of tasks that don't depend on any previous computation)

But I don't know anything about concurrency and don't know where to learn it.

Have you profiled your code? If you're concerned about performance, before you jump to an entirely new magnitude of complexity, find out exactly what is taking a long time.

mcw
Jul 28, 2005

Aleksei Vasiliev posted:

Where can I find a good tutorial on concurrency?

Hopefully the good folks in this thread have helped you to find a short-term solution; but if you're still interested in this topic, there's a book called Java Concurrency in Practice that is (in my opinion) worth a read for anyone who's writing Java.

Luminous
May 19, 2004

Girls
Games
Gains

MariusMcG posted:

Hopefully the good folks in this thread have helped you to find a short-term solution; but if you're still interested in this topic, there's a book called Java Concurrency in Practice that is (in my opinion) worth a read for anyone who's writing Java.

Man, I saw the question, and starting reading the replies, just waiting, hoping, nobody would post this so that I could do so. This is a really great book for understanding threading issues in general, and getting a grip on what Java can provide to you.

Paolomania
Apr 26, 2006

Luminous posted:

Man, I saw the question, and starting reading the replies, just waiting, hoping, nobody would post this so that I could do so. This is a really great book for understanding threading issues in general, and getting a grip on what Java can provide to you.

This book keeps good company.

trex eaterofcadrs
Jun 17, 2005
My lack of understanding is only exceeded by my lack of concern.

Paolomania posted:

This book keeps good company.



I have that same TAOCP collection. I HATE how he's releasing the individual fascicles for 4. I keep forgetting which I already have.

Adbot
ADBOT LOVES YOU

mister_gosh
May 24, 2002

Here's an easy one for you guys. What does the ;; mean here?

code:
for (;;) {
  // stuff
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply