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:
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.|
|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).|
This page is posted
Optional Replicator mirror
|no blog for this page||Canadian
Your face IP:[18.104.22.168]
You are visitor number|