1. Diff between Green Thread and Native Thread ?
Green Thread is a thread machanism of JVM itself and Native thread is OS's thread machanism.
2. What is CountDownLatch in java concurrency ?
Ans: CountDownLatch
3. What is CyclicBarrier in java concurrency ?
Ans: CyclicBarrier and example 2
4. Diff between Lock, Intrinsic lock and Reentrant Sync ?
5. Executors vs Thread pool
6. Daemon Thread
7. How we can get all active threads from Thread class ?
http://www.journaldev.com/1162/java-multi-threading-concurrency-interview-questions-with-answers
Green Thread is a thread machanism of JVM itself and Native thread is OS's thread machanism.
2. What is CountDownLatch in java concurrency ?
Ans: CountDownLatch
3. What is CyclicBarrier in java concurrency ?
Ans: CyclicBarrier and example 2
4. Diff between Lock, Intrinsic lock and Reentrant Sync ?
5. Executors vs Thread pool
6. Daemon Thread
7. How we can get all active threads from Thread class ?
http://www.journaldev.com/1162/java-multi-threading-concurrency-interview-questions-with-answers
Java
Threads Important points
A class invariant is a type of internal
invariant that applies to every instance of a class at all times, except when
an instance is in transition from one consistent state to another. A class
invariant can specify the relationships among multiple attributes, and should
be true before and after any method completes. For example, suppose you
implement a balanced tree data structure of some sort. A class invariant might
be that the tree is balanced and properly ordered.
A class is thread‐safe if it behaves
correctly when accessed from multiple threads, regardless of the scheduling or
interleaving of the execution of those threads by the runtime environment
To avoid race conditions, there must be a way
to prevent other threads from using a variable while we're in the middle of
modifying it
CHECK‐THEN‐ACT RACE CONDITION:‐ you observe something to be true (file X doesn't exist) and
then take action based on that observation (create X); but in fact the
observation could have become invalid between the time you observed it and the
time you acted on it (someone else created X in the meantime), causing a
problem (unexpected exception, overwritten data, file corruption).
Every Java object can implicitly act as a lock
for purposes of synchronization; these built‐in locks are called intrinsic locks or monitor locks
When a thread requests a lock that is already
held by another thread, the requesting thread blocks. But because intrinsic
locks are reentrant, if a thread tries to acquire a lock that it already holds,
the request succeeds. Reentrancy means that locks are acquired on a per‐thread rather than per‐invocation basis.
For each mutable state variable that may be
accessed by more than one thread, all
accesses to that variable must be performed with the same lock held. In this case, we say that the variable is guarded
by that lock. For every invariant that involves more than one variable, all the variables involved in that
invariant must be guarded by the same
lock .
Acquiring the lock associated with an object
does not prevent other threads from accessing that object ‐ the only thing that
acquiring a lock prevents any other thread from doing is acquiring that same lock
While synchronized methods can make individual
operations atomic, additional locking is required ‐ when multiple operations
are combined into a compound action.
Any access (get or set) to Global/state
variables should be done within the synchronized methods or same lock.This will
ensure the visibility of state variables across the threads i.e. To ensure that all threads see the most upto‐date values of shared
mutable variables, the reading and writing threads must synchronize on a common
lock.
There is no guarantee that operations in one
thread will be performed in the order given by the program, as long as the
reordering is not detectable from within that thread ‐ even if the reordering
is apparent to other threads.
When a field is declared volatile, the compiler and runtime are put on notice that this
variable is shared and that operations on it should not be reordered with other
memory operation
You can use volatile variables only when all the following criteria are met:
• Writes to the variable do not depend on its
current value, or you can ensure that only a single thread ever updates the value;
• The variable does not participate in
invariants with other state variables; and
•
Locking is not required for any other reason while the variable is being
accessed
Publishing an object means making it available to code outside of its
current scope, such as by storing a reference to it where other code can find
it, returning it from a non‐private method, or passing it to a method in another class.
To publish an object safely, both the
reference to the object and the object's state must be made visible to other
threads at the same time. A properly constructed object can be safely published
by:
•
Initializing an object reference from a static initializer;
• Storing a reference to it into a volatile
field or AtomicReference;
• Storing a reference to it into a final field
of a properly constructed object; or •
Storing a reference to it into a field that is properly guarded by a lock
The publication requirements for an object
depend on its mutability:
•
Immutable objects can be published through any mechanism;
• Effectively immutable objects must be safely
published;
• Mutable objects must be safely published,
and must be either thread‐safe or guarded by a lock.
An object that is published when it should not have been is said to have escaped.
If data is only accessed from a single thread,
no synchronization is needed. This technique, thread confinement, is one of the simplest ways to achieve thread
safety
Stack
confinement is a special case of thread confinement in
which an object can only be reached through local variables
Immutable
objects are always thread‐safe. An object is
immutable if:
• Its state cannot be
modified after construction;
• All its fields are final; and
• It is
properly constructed (the this reference does not escape during construction).
Race
conditions in accessing or updating multiple related
variables can be eliminated by using an immutable object to hold all the
variables. With a mutable holder object,
you would have to use locking to ensure atomicity; with an immutable one, once
a thread acquires a reference to it, it need never worry about another thread
modifying its state. If the variables are to be updated, a new holder object is
created, but any threads working with the previous holder still see it in a
consistent state
The most useful policies for using and sharing
objects in a concurrent program are:
Thread-confined. A thread‐confined object is owned exclusively by and confined to one
thread, and can be modified by its owning thread.
Shared
read-only. A shared read‐only object can be accessed concurrently by multiple threads
without additional synchronization, but cannot be modified by any thread.
Shared read‐only objects include
immutable and effectively immutable objects.
Shared
thread-safe. A thread‐safe object performs synchronization internally, so multiple
threads can freely access it through its public interface without further
synchronization
Guarded. A guarded object can be accessed only with a specific lock
held. Guarded objects include those that are encapsulated within other thread‐safe objects and
published objects that are known to be guarded by a specific lock.
When an object is encapsulated within another object, all code paths that have access
to the encapsulated object are known and can be therefore be analyzed more
easily than if that object were accessible to the entire program. Combining
confinement with an appropriate locking discipline can ensure that otherwise
non‐thread‐safe objects are used in
a thread‐safe manner.
An object following the Java monitor pattern
encapsulates all its mutable state and guards it with the object's own
intrinsic lock. The Java monitor pattern is useful when building classes from
scratch or composing classes out of objects that are not thread‐safe.
The safest way to add a new atomic operation
is to modify the original class to support the desired operation, but this is not always possible
because you may not have access to the source code or may not be free to modify
it. 2. Another approach is to extend the class, assuming it was designed for
extension. E.g:-BetterVector in extends Vector to add a putIfAbsent method
No comments:
Post a Comment