Java synchronizing static list?
In a开发者_JS百科 Java class , i am having a static list so this list is shared across all the objects of this class.The business logic in this class will run periodically which is invoked by some method with out passing instance parameters.Now I want to invoke this run method based on the list(I will add some vales into this list based on JMS) ,this list may empty sometimes and after finishing the run , i am emptying this list.Now my question is , whether I need to synchronize this list or not?
Also let me know is there any other way to pass value in one object instance(Thread1) to other object instance (Thread2) other than having Static variable(static list)?
Thx
you will either need to synchronize all read and writes to this list, or, use a multithreaded capable list (like CopyOnWriteArrayList, or even a ConcurrentMap if you are using that for more sophisticated stuff).
Otherwise, you will need to have good concurrency control so that different threads dont overwrite each other, and also that other threads get to see changes that get made.
re edit: the best way to pass data between threads is for them to share a data structure. Static variables is one way, but its not the only way to share. You can share via a common object that is passed in both threads (in the constructor for example). Usually, this is called a queue, where one thread writes, and the other threads consumes from. In java, there are some blocking queues to make this easier - see the many different classes in this package http://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/package-summary.html
If the list is mutable and accessed by different threads (which it sounds like it is), then yes, you need to synchronize. (If it's immutable, then another option is to make the static reference to it final.)
I would suggest taking a look initially at the BlockingQueue classes, which are designed to allow one thread (or indeed multiple threads) to add items to a "list" and then have another thread sit pulling items off and processing them.
Also let me know is there any other way to pass value in one object instance(Thread1) to other object instance (Thread2) other than having Static variable(static list)?
object instance(Thread1) to other object instance (Thread2) --> Need static variable since object instances are different. However as you know, if Thread1 and Thread2 are operating on same objects, then instance variables of the class will be shared between threads. So no need to make them static.
If there is any possibility of access and/or updates from different threads, then you do need to synchronize those operations.
Or to put it another way, the only cases where you can dispense with synchronizing operations on the list are when :
- there is only one thread that can possibly access / update the list, or
- the list is created, initialized, wrapped in an immutable list wrapper and safely published by one thread ... and then never updated.
Also let me know is there any other way to pass value in one object instance(Thread1) to other object instance (Thread2) other than having Static variable(static list)?
There are many ways. For example :
You could arrange that thread2's runnable has a public setter that thread1's runnable can use to pass a value to thread2. This requires some additional synchronization.
You could arrange that thread1 and thread2 are instantiated with a shared object or objects that can be used to pass spate back and forth. If the object is a general purpose (synchronized) queue or pipe or whatever, the threads won't need to do any explicit synchronization.
Also let me know is there any other way to pass value in one object instance(Thread1) to other object instance (Thread2) other than having Static variable(static list)?
Here are two different methods which can avoid the use of a static variable here. There may be more.
Method #1
class A implements Runnable {
final Object x;
public A (Object _x) {
x = _x;
}
...
}
// elsewhere .. hopefully from a NON-STATIC context
// where theObjectToShare is available
A th1 = new Thread(new A(theObjectToShare));
...
And method #2A/B:
object parentMemberVariable = ...;
function runStuff () {
object _localFinal = parentMemberVariable;
A th1 = new Thread(new Runnable {
public void Run () {
// NON-STATIC inner classes (including anonymous) can access
// parents member variables. this is because there are created
// "in the context of" the parent class.
// This could also be done for the normal inner Runnables.
foo(parentMemberVariable);
// anonymous classes can also access final variables
// in scope at declaration
foo(_localFinal);
}
});
Happy coding.
精彩评论