Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Some questions on java multithreading,

I have a set of questions regarding Java multithreading issues. Please provide me with as much help as you can.

0) Assume we have 2 banking accounts and we need to transfer money between them in a thread-safe way. i.e.

accountA.money += transferSum; 
accountB.money -= transferSum; 

Two requirements exist:

  1. no one should be able to see the intermediate results of the operation (i.e. one acount sum is increased, but others is not yet decreased)
  2. reading access should not be blocked during the operation (i.e. old values of account sums should be shown during the operation goes on)

Can you suggest some ideas on this?

1) Assume 2 threads modify some class field via synchronized method or utilizing an explicit lock. Regardless of synchronization, there are no guarantee that this field will be visible to threads, that read it via NOT synchronized method. - is it correct?

2) How long a thread that is awoken by notify method can wait for a lock? Assume we have a code like this:

synchronized(lock) {  
    lock.notifyall();   
    //do some very-very long activity  
    lock.wait() //or the end of synchronized block  
}  

Can we state that at least one thread will succeed and grab the lock? Can a signal be lost due to some timeout?

3) A quotation from Java Concurrency Book:

"Single-threaded executors also provide sufficient internal synchronization to guarantee that any memory writes made by tasks are visible to subsequent tasks; this means that objects can be safely confined to the "task thread" even though that thread may be replaced with another from time to time."

Does this mean that the only thread-safety issue that remains for a code being executed in single-threaded executor is data race and we can abandon the volatile variables and overlook all visibility issues? It looks like a universal way to solve a great part of concurrency issues.

4) All standard getters and setters are atomic. They need not to be synchronized if the field is marked as volatile. - is it correct?

5) The initiation of static fields and static blocks is accomplished by one thread and thus need not to be synchronized. - is it correct?

6) Why a thread needs to notify others if it leaves the lock with wait() method, but does not need to do this if it leaves the lock by exiting the synchronized block?

like image 643
MiamiBeach Avatar asked Jul 22 '11 11:07

MiamiBeach


People also ask

Does Java provide the multi threading feature yes or no?

Java supports multithreading through Thread class. Java Thread allows us to create a lightweight process that executes some tasks. We can create multiple threads in our program and start them. Java runtime will take care of creating machine-level instructions and work with OS to execute them in parallel.

What are the issue might appear in multithreading?

Memory-interference, race conditions, deadlock, livelock, and starvation are an example of some problems that come with multithreading and concurrent programming. There is no end of a problem; if you get it wrong, they will be hard to detect and debug.

Can Java object be locked down for exclusive use by a given thread?

23)Can Java object be locked down for exclusive use by a given thread? Yes. You can lock an object by putting it in a "synchronized" block. The locked object is inaccessible to any thread other than the one that explicitly claimed it.

Where multithreading is used in Java?

However, we use multithreading than multiprocessing because threads use a shared memory area. They don't allocate separate memory area so saves memory, and context-switching between the threads takes less time than process. Java Multithreading is mostly used in games, animation, etc.


1 Answers

0: You can't.

Assuring an atomic update is easy: you synchronize on whatever object holds the bank accounts. But then you either block all readers (because they synchronize as well), or you can't guarantee what the reader will see.

BUT, in a large-scale system such as a banking system, locking on frequently-accessed objects is a bad idea, as it introduces waits into the system. In the specific case of changing two values, this might not be an issue: it will happen so fast that most accesses will be uncontended.

There are certainly ways to avoid such race conditions. Databases do a pretty good job for ba nk accounts (although ultimately they rely on contended access to the end of a transaction).

1) To the best of my knowledge, there are no guarantees other than those established by synchronized or volatile. If one thread makes a synchronized access and one thread does not, the unsynchronized access does not have a memory barrier. (if I'm wrong, I'm sure that I'll be corrected or at least downvoted)

2) To quote that JavaDoc: "The awakened threads will not be able to proceed until the current thread relinquishes the lock on this object." If you decide to throw a sleep into that synchronized block, you'll be unhappy.

3) I'd have to read that quote several times to be sure, but I believe that "single-threaded executor" is the key phrase. If the executor is running only a single thread, then there is a strict happens-before relationship for all operations on that thread. It does not mean that other threads, running in other executors, can ignore synchronization.

4) No. long and double are not atomic (see the JVM spec). Use an AtomicXXX object if you want unsynchronized access to member variables.

5) No. I couldn't find an exact reference in the JVM spec, but section 2.17.5 implies that multiple threads may initialize classes.

6) Because all threads wait until one thread does a notify. If you're in a synchronized block, and leave it with a wait and no notify, every thread will be waiting for a notification that will never happen.

like image 184
parsifal Avatar answered Sep 21 '22 15:09

parsifal