Here are your tools for writing thread-safe code.
Does the synchronized mechanism lock Threads out of the object in all critical regions or the object in just one critical region? It is the first. All critical sections locked with the same object are blocked. Keep in mind that you can use an object other than the one you are working on as the locking object. This would let you for example allow two groups of critical code to be executing simultaneously, provided they locked on different objects, e.g. a dummy inner class locking object. Understand that the objects themselves are not locked. Other threads can access them with non-sychronised methods, even when they are locked. It also means you could have critical code acting on thousands of different objects funnelled to single processing stream by locking all the critical code on a single lock object. This would not be efficient, but would be theoretically possible.
Unfortunately you can’t use interrupt to abort just any i/o. It can really only be used for that when using the Java version 1.4 java.nio I/O. In particular when using a Channel that implements InterruptibleChannel, which includes channels for files, pipes and networking. Thread.interrupt is not guaranteed to wake up any thread blocked in any other I/O operation.
See the warning under Gotchas:Threads on why a sleeping task may never waken if somebody fiddles with the system clock setting while your thread is asleep.
The easiest way to start a Thread is to implement Runnable on some class. All you have to do is say implements Runnable and write a run method that is called when the Thread forks (starts). However you don’t call run directly.
// running on the same thread aRunnable.run();
If you do, run will be called like a normal method, with no new Thread created. You must create a Thread object and then call start on the Thread object instead.
// starting a Thread Thread thread = new Thread( aRunnable ); thread.start(); // which will then execute arunnable.run() on a separate Thread.
You are not on the Swing event thread when main first starts up! You are on it in your event listeners. You are tell if you are on it with:
// Either method will work in Java version 1.3 or later // to determine if you are running on the dispatch thread, // the same for AWT (Advanced Windowing Toolkit) or Swing. // in Swing Boolean onSwingThread = javax. swing.SwingUtilities. isEventDispatchThread(); // in AWT Boolean onDispatchThread = java. awt.EventQueue. isDispatchThread(); // Dump info about the current thread, name, priority, group. System. out.println ( Thread. currentThread() ); // Dump name of the current thread System. out.println ( Thread. currentThread(). getName() );
One of the most common errors is to tie up the AWT/Swing event thread with some long running computation or even a sleep. Everything freezes up. The GUI (Graphic User Interface) can’t respond to mouse clicks and no repainting happens. You have to spin the time-consuming task off on its own thread or use a Timer.is a Sun class that is not part of the JDK (Java Development Kit). It lets you convert some long-running event handling code into a separate thread with just a line of extra code.
If you violate these rules, the entire system starts to behave unpredictably and irrationally. If by violating these rules, you manage to create two event-processing threads, life gets really interesting as they unpredictably fight with each other handling Swing events.
|thread 1||thread 2|
You would get an erroneous result balance + depositAmount1 rather than balance + depositAmount1 + depositAmount2.
If instead you wrote:
Then only one thread at a time could access the account record containing the balance field, and the code would have to run like this:
|thread 1||thread 2|
To have multi-thread code work, you need more than just atomic method calls.
For example, imagine a banking system with a getBalance() method to examine the balance, and another withdraw( long withdrawAmount) method to update the a balance.In a naïve system, the teller might first do a transaction that calls the checkBalance() method to look at the balance, and if it has sufficient funds, calls the withdraw method to update the balance.
However, between the method call to look at the balance and update the balance, another withdrawal transaction could come in and snaffle the funds. The withdrawal would improperly go ahead, leaving a correctly-computed overdraft.
|thread 1||thread 2|
|check balance big enough for withdrawal1|
|check balance big enough for withdrawal2|
|withdraw ( withdrawalAmount1)|
For such code to work in a thread-safe way, the withdrawal method must do an atomic integral last-minute check on the balance, as well as an atomic increment on the balance such as the sample code for a withdrawal in the example on why synchronized is needed.
One trick you can use for static variable contention is to introduce static references to dummy lock objects new Object(). Instead of locking the whole class, you lock just one of the lock objects which represents access to some subset of the member variables. You can also use the technique for instance variables in objects with many threads competing for access.
|recommend book⇒Java Concurrency in Practice|
|by||Brian Goetz, Tim Peierls, Joshua J. Bloch, Joseph Bowbeer, David Holmes, Doug Lea||978-0-321-34960-6||paperback|
|Bloch and Lea especially have very good reputations in concurrent programming. This is the dream team to write such a book.|
|Greyed out stores probably do not have the item in stock. Try looking for it with a bookfinder.|
|recommend book⇒Concurrent Programming in Java(TM): Design Principles and Patterns, third edition|
|This book is not in stock at any of the major online bookstores. Try looking for it with a bookfinder. Threads and concurrency in Java, design considerations (safety, liveness, and performance), Before/After Patterns, layering, adapters, immutability and synchronization, deadlock, resource ordering, the Java Memory Model and concurrency, using the java.concurrency package, confinement, refactoring for concurrency, mutexes, read-write locks, recovering from failure, notifications, semaphores, latches, exchanges, transactions, one-way messages, worker threads, polling and event-driven I/O, parallelism techniques (fork/join, computation trees, and barriers), Communicating Sequential Processes (CSP).|
available on the web at:
optional Replicator mirror
Please email your feedback for publication, letters to the editor, errors, omissions, typos, formatting errors, ambiguities, unclear wording, broken/redirected link reports, suggestions to improve this page or comments to Roedy Green : . If you want your message, your name or email kept confidential, not considered for public posting, please explicitly specify that. Unless you state otherwise, I will treat your message as a letter to the editor that I may or may not publish in the feedback section. After that, it will be too late to retract it. If you disagree with something I said, especially when sending an ad-hominem attack, a rant composed mainly of obscenities or a death threat, please quote the offending passage and cite the web page where you found it, tell me why you think it is wrong, and, if possible, provide some supporting evidence. I can’t very well fix erroneous or ambiguous text if I can’t find it.
Your face IP:[188.8.131.52]
|Feedback||You are visitor number 98,793.|