Even trivial Java apps are designed to run on multi-CPU machines with execution streams running in parallel. Each stream is called a thread. Each thread, by default, gets one megabyte of virtual RAM (Random Access Memory) reserved for its stack just in case it wants to grow. So 2000 threads would require 2 gig of virtual RAM, — which all by itself would fill the largest possible 32-bit virtual RAM space in a Wintel machine. You can configure this the stack space per thread on the java.exe command line with the -Xss 640000 option to configure a 640K stack.
Natural Bridge used a hybrid of green and native which allows scalability to thousands of threads. An early Solaris Java had green threads. Pretty well the rest of thread implementations are native. You, as application programmer, have no way, in pure Java, to control which kind of threads are used.
The good news is, even though you are using Runnable, you don’t have the overhead of actually creating a new Thread since you are just calling the run method on the already existing Swing Thread.
You are not on the Swing event thread when main first starts up! You are on it
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 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.
There are two fundamental things to understand about Swing and threads:
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.
In general, multi-thread code is tricky, however, if you can arrange that threads don’t modify the same variables or look at variables other threads are modifying, just look at the same final variables, there is nothing to Threads. You don’t need any synchronization. Local variables are private to each thread so they are not a problem either.
Where practical, use existing thread-safe objects, like AtomicLong, to manage your class’s state. It is simpler to reason about the possible states and state transitions for existing thread-safe objects that it is for arbitrary state variables and his makes it easier to maintain and verify thread safety.With the following basic tools you can craft all manner of complex interactions.
~ Brian Goetz Java Concurrency in Practice page 23
All you need is a class, perhaps the current one that has a run method and that has implements Runnable on the class declaration. Here is a simple example of such a class:
The run method gets executed on a separate thread. When run returns, the thread dies and cannot be revived or restarted. Don’t call a Runnable’s run method directly. If you do, you will not start a new Thread; you will just run the method in the ordinary way on the current thread. You must use start which creates a new thread and then calls run for you. To start the new thread you need some code like this:
// execute InParallel.run() // in parallel to this thread on a new thread. Thread t = new Thread ( new InParallel() ); // Note we call t.start(), not t.run() // t.run() would just call run in the ordinary way. t.start();
Don’t forget to set your thread variable (t in the example above) to null when you no longer need it. You don’t have to wait till the thread terminates. If you don’t, you will end up with a useless dead Thread object cluttering your heap.
There is another technique where you extend the Thread class and override its run method, but it is not as flexible.
ThreadLocal is a technique of providing per-thread variables that without having to build them into the Thread object. Roughly speaking it makes a static variable into an automatically managed array, one slot per each active thread.
was not originally part of JDK (Java Development Kit). You had to it separately. It lets you convert some long-running event handling code into a separate thread with just a line of extra code.You can put the current Thread to sleep for a period of time. It will awake prematurely if some other thread does a thread.interrupt() to it. It that case it will wake with an exception rather than naturally.
try { // put current thread to sleep Thread.sleep( delayInMilliseconds ); } catch ( InterruptedException e ) { out.println( "some other thread woke me prematurely." ) }
// Bump up a thread's priority to the cpu // one notch above the usual. thread.setPriority( Thread.NORM_PRIORITY + 1 ); // Drop up the thread's priority two notches below // where it is now. thread.setPriority( thread.getPriority() - 2 );
Threads of equal priority are not necessarily scheduled round-robin style. One Thread can hog the CPU indefinitely squeezing out all the other Threads of equal priority even if the Threads call yield every once in a while to give the other Threads of equal priority a kick at the cat.
You may starve Swing so it never gets a chance to paint anything, even if you are on a separate Thread.
// Get reference to the thread running this // code right now. Thread runningNow = Thread.currentThread();
The lock part of every Object is called the monitor.
Note that the exact same critical code section may be executing simultaneously so long as it locks on different objects. You don’t always lock on this.
Because synchronized blocks can be nested, it is possible for thread to lock multiple objects at once. Then you have the potential for deadlock. If thread a has object 1 locked and wants object 2 and thread b has object 2 locked and wants object 1, they will stare at each other, waiting indefinitely in a Mexican standoff, sometimes called a deadly embrace. One way to avoid this is to always lock your objects is the same canonical order, always 1 before 2 using some convention you concoct to determine the standard order.
If you wanted two different critical sections to be able to execute simultaneously on the same object, to maximise speed in a multi-CPU machine or in critical sections that do i/o, you would need to create an auxiliary dummy locking object appended to (referenced by) the main object for the second critical region to use for its synchronized lock object, typically of type Object.
Once you understand these basics, you can go on to more complex tasks like co-operating producer-consumer threads that wait on each other and ways of allowing simultaneous read of a structure but only single-thread update.
Further, any variables that more than one thread might be changing have to be marked volatile to warn other threads to always look for a fresh copy of the value rather than relying on a their own cached copy.
With wait, you first must gain a lock on an object with synchronized, then you check if you really need to wait. If you do, then you call Object.wait() on the lock object. This puts your Thread to sleep and releases the lock so that other threads might have it. Eventually some other thread awakens you from your slumber by calling Object.notify() or Object.notifyAll() on the lock object. You wake up then get in line waiting the reacquire the lock. When you finally do, you continue execution. In other words, you wait for some other thread to complete some work and notify you when it is done. The notifier thread needs to own the lock to be able to call notify and it must release the lock before any of the waiting threads will be able to resume.
Most of the time in all this, the object is not kept locked. It is only locked for short periods to check if waiting is really necessary and do the wait or notify.
You might say that synchronized in for updating related groups of fields, where volatile is for updating independent single fields.
Particularly in a multi-CPU situation, you have a problem with caching. Each CPU keeps copies of variables in registers and in various hardware RAM caches. If another CPU changes a variable, it may automatically refresh the other CPU s' caches, but it certainly won’t automatically refresh any other CPU ’s registers. This means a CPU may be using a stale copy of a variable’s value and not know it. When you declare a variable volatile it warns the compiler to generate code to fetch the value freshly from RAM every time it is needed, even if it already has a copy it has not recently changed itself sitting in a register. Further, it warns the compiler to generate code to store the value into RAM every time it is changed so that other threads will immediately see the new value.
The same problem happens with less frequency in a single CPU system since each thread has its own virtual set of registers.
Despite what you may read elsewhere, volatile is not sufficient to make x++ into an atomic operation. Patricia Shanahan proved this experimentally. atomic means indivisible, not high-powered. Even with if x were declared Volatile, the thread will not necessarily get to complete the load, add, store in one operation without some other thread meddling with the x variable.
I have heard conflicting stories on just how synchronized and volatile mesh. It is safe to use them together: a volatile reference in a synchronized block. Some say you can use synchronized without volatile, but not volatile without synchronized in at least one of the threads. Others say you can use volatile on its own as well.
It seems to me, you would be safest to declare any variable examined by different threads as volatile whether you do all access inside synchronized or not. However, this is probably belt and suspenders and might generate unnecessarily slow code. If I were designing the system, volatile would only be needed when there is some unsynchronized access. Experiments are not enough. That determines behaviour with only one compiler-JVM combination. Someday I will wade through the specs to find out how these keywords are supposed to work.
I presume when you enter a synchronized block the compiler freshly loads all values it needs and when you exit it makes sure all are stored so that other CPUs (Central Processing Units) can see the new value. While it is inside the block it need not treat all variables as automatically volatile, since no other critical code is running. If someone can confirm or refute this assumption, please let me know.
Working with unsynchronized volatile data is very difficult to get solidly right. Treat it with just as much caution as you would unprotected volatile variables in a multi-threaded C or assembly language program. Reserve it for these few situations:
The problem is misuse of these features creates very subtle bugs that may not show up for days, or only when run on certain machines. You really do need a deep understanding of this, something I do not have yet. Unfortunately, trying to escape learning by being overly conservative also imparts a big speed penalty.
This is a gross oversimplification of what java.util.concurrent does, however, it might be a useful framework to use to dive in to the detail. You write little hunks of code conforming to an interface, then queue them up to be scheduled concurrently. There are three interfaces.
If you have an Applet, convert it into a hybrid that can also be run as an application. For details how see Applet. When a GUI is running, most of the time it should be idle, just waiting for the next event. If you hit Ctrl-Break (Ctrl-\ in Linux?) in the console window, it will interrupt and tell you what all the threads were doing. If the event thread is busy running application code something is amiss. Also monitor some known well-behaved GUI apps so you get an idea the sort of behaviour you should find. You will be surprised just how many threads are in there.
To catch yourself pestering Swing from the wrong thread try the ThreadCheckingRepaintManager. It checks that all repaint events came from the event thread. This won’t catch all your blunders, but it will catch most of them.
If your threads do interact, writing bug free code is extremely difficult. Your code will work most of time and then unexpectedly freeze during the big demo. You have to write the code using pure logic and paranoia, not just trying things and testing. As much as possible, use packages to handle your thread interaction problems. The authors of these packages specialise in the arcane art. Further, there are thousands of eyes checking the package for flaws.
Let me repeat that for emphasis, the practical solution to bugs is to throw out as much of your home-brew Thread logic as possible and replace it with standard library code from the java.util.concurrent package.
This code will be much higher quality than anything you will be able to write because:
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 | |||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
publisher | Addison-Wesley | 978-0-13-270225-6 | eBook | |||||||||||||||||||||||||||||||||||||||||||||||||||||
published | 2006-05-19 | B004V9OA84 | kindle | |||||||||||||||||||||||||||||||||||||||||||||||||||||
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 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
by | Douglas Lea | 978-0-321-25617-1 | paperback | |||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
publisher | Addison-Wesley | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
published | 2006-05-19 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
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). | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Greyed out stores probably do not have the item in stock. Try looking for it with a bookfinder. |
recommend book⇒Thinking In Java, fourth edition | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
by | Bruce Eckel | 978-0-13-187248-6 | paperback | |||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
birth | 1957-07-08 age:60 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
publisher | Prentice Hall | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
published | 2006-02-20 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
read online. Good if you want to understand the philosophy behind Java. It does not cover Java 1.5 or later, e.g. enums, generics, for:each loops, annotations. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Greyed out stores probably do not have the item in stock. Try looking for it with a bookfinder. |
recommend book⇒Java Threads, third edition | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
by | Scott Oaks, Henry Wong | 978-0-596-00782-9 | paperback | |||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
publisher | O’Reilly | 978-1-4493-6666-7 | eBook | |||||||||||||||||||||||||||||||||||||||||||||||||||||
published | 2004-09-10 | B00BIRRRZA | kindle | |||||||||||||||||||||||||||||||||||||||||||||||||||||
An introductory book with good examples. Not as deep as you would usually expect from O’Reilly. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Greyed out stores probably do not have the item in stock. Try looking for it with a bookfinder. |
recommend book⇒Taming Java Threads | ||||
by | Allen Holub | 978-1-893115-10-1 | paperback | |
---|---|---|---|---|
birth | 1955 age:62 | B001GMAPVA | kindle | |
publisher | Apress | |||
published | 2000-06-01 | |||
Greyed out stores probably do not have the item in stock. Try looking for it with a bookfinder. |
recommend book⇒Java Thread Programming | ||||
by | Paul Hyde | 978-0-672-31585-5 | paperback | |
---|---|---|---|---|
publisher | Sams | |||
published | 1999-08-30 | |||
Greyed out stores probably do not have the item in stock. Try looking for it with a bookfinder. |
This page is posted |
http://mindprod.com/jgloss/thread.html | |
Optional Replicator mirror
|
J:\mindprod\jgloss\thread.html | |
Please read the feedback from other visitors,
or send your own feedback about the site. Contact Roedy. Please feel free to link to this page without explicit permission. | ||
Canadian
Mind
Products
IP:[65.110.21.43] Your face IP:[44.200.122.214] |
| |
Feedback |
You are visitor number | |