ReentrantReadWriteLock has a fair and non-fair(default) mode, but the document is so hard for me to understand it.
How can I understand it? It's great if there is some code example to demo it.
UPDATE
If I have a writing thread, and many many reading thread, which mode is better to use? If I use non-fair mode, is it possible the writing thread has little chance to get the lock?
Non-fair means that when the lock is ready to be obtained by a new thread, the lock gives no guarantees to the fairness of who obtains the lock (assuming there are multiple threads requesting the lock at the time). In other words, it is conceivable that one thread might be continuously starved because other threads always manage to arbitrarily get the lock instead of it.
Fair mode acts more like first-come-first-served, where threads are guaranteed some level of fairness that they will obtain the lock in a fair manner (e.g. before a thread that started waiting long after).
Edit
Here is an example program that demonstrates the fairness of locks (in that write lock requests for a fair lock are first come, first served). Compare the results when FAIR = true (the threads are always served in order) versus FAIR = false (the threads are sometimes served out of order).
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class FairLocking {
public static final boolean FAIR = true;
private static final int NUM_THREADS = 3;
private static volatile int expectedIndex = 0;
public static void main(String[] args) throws InterruptedException {
ReentrantReadWriteLock.WriteLock lock = new ReentrantReadWriteLock(FAIR).writeLock();
// we grab the lock to start to make sure the threads don't start until we're ready
lock.lock();
for (int i = 0; i < NUM_THREADS; i++) {
new Thread(new ExampleRunnable(i, lock)).start();
// a cheap way to make sure that runnable 0 requests the first lock
// before runnable 1
Thread.sleep(10);
}
// let the threads go
lock.unlock();
}
private static class ExampleRunnable implements Runnable {
private final int index;
private final ReentrantReadWriteLock.WriteLock writeLock;
public ExampleRunnable(int index, ReentrantReadWriteLock.WriteLock writeLock) {
this.index = index;
this.writeLock = writeLock;
}
public void run() {
while(true) {
writeLock.lock();
try {
// this sleep is a cheap way to make sure the previous thread loops
// around before another thread grabs the lock, does its work,
// loops around and requests the lock again ahead of it.
Thread.sleep(10);
} catch (InterruptedException e) {
//ignored
}
if (index != expectedIndex) {
System.out.printf("Unexpected thread obtained lock! " +
"Expected: %d Actual: %d%n", expectedIndex, index);
System.exit(0);
}
expectedIndex = (expectedIndex+1) % NUM_THREADS;
writeLock.unlock();
}
}
}
}
Edit (again)
Regarding your update, with non-fair locking it's not that there's a possibility that a thread will have a low chance of getting a lock, but rather that there's a low chance that a thread will have to wait a bit.
Now, typically as the starvation period increases, the probability of that length of time actually occuring decreases...just as flipping a coin "heads" 10 consecutive times is less likely to occur than flipping a coin "heads" 9 consecutive times.
But if the selection algorithm for multiple waiting threads was something non-randomized, like "the thread with the alphabetically-first name always gets the lock" then you might have a real problem because the probability does not necessarily decrease as the thread gets more and more starved...if a coin is weighted to "heads" 10 consecutive heads is essentially as likely as 9 consecutive heads.
I believe that in implementations of non-fair locking a somewhat "fair" coin is used. So the question really becomes fairness (and thus, latency) vs throughput. Using non-fair locking typically results in better throughput but at the expense of the occasional spike in latency for a lock request. Which is better for you depends on your own requirements.
When some threads waiting for a lock, and the lock has to select one thread to get the access to the critical section:
In non-fair mode, it selects thread without any criteria.
In fair mode, it selects thread that has waiting for the most time.
Note: Take into account that the behavior explained previously is only used with the lock() and unlock() methods. As the tryLock() method doesn't put the thread to sleep if the Lock interface is used, the fair attribute doesn't affect its functionality.
Related
I am learning multi-threads programming in java recently. And I don't understand why the following test case will fail. Any explanation will be much appreciated.
Here is MyCounter.java.
public class MyCounter {
private int count;
public synchronized void incrementSynchronized() throws InterruptedException {
int temp = count;
wait(100); // <-----
count = temp + 1;
}
public int getCount() {
return count;
}
}
This is my unit test class.
public class MyCounterTest {
#Test
public void testSummationWithConcurrency() throws InterruptedException {
int numberOfThreads = 100;
ExecutorService service = Executors.newFixedThreadPool(10);
CountDownLatch latch = new CountDownLatch(numberOfThreads);
MyCounter counter = new MyCounter();
for (int i = 0; i < numberOfThreads; i++) {
service.submit(() -> {
try {
counter.incrementSynchronized();
} catch (InterruptedException e) {
e.printStackTrace();
}
latch.countDown();
});
}
latch.await();
assertEquals(numberOfThreads, counter.getCount());
}
}
But if I remove wait(100) from the synchronized method incrementSynchronized, the test will succeed. I don't understand why wait(100) will affect the result.
Solomons suggestion to use sleep is a good one. If you use sleep instead of wait, you should see the test pass.
Using wait causes the thread to relinquish the lock, allowing other threads to proceed and overwrite the value in count. When the thread's wait times out, it acquires the lock again, then writes a value to count that may be stale by now.
The typical usage of wait is when your thread can't do anything useful until some condition is met. Some other thread eventually satisfies that condition and a notification gets sent that will inform the thread it can resume work. In the meantime, since there is nothing useful the thread can do, it releases the lock it is holding (because other threads need the lock in order to make progress meeting the condition that the thread is waiting for) and goes dormant.
Sleep doesn't release the lock so there won't be interference from other threads. For either the sleeping case or the case where you delete the wait call, the lock is held for the duration of the operation, nothing else can change count, so it is threadsafe.
Be aware that in real life, outside of learning exercises, sleeping with a lock held is usually not a great idea. You want to minimize the time that a task holds a lock so you can get more throughput. Threads denying each other the use of a lock is not helpful.
Also be aware that getCount needs to be synchronized as well, since it is reading a value written by another thread.
I was trying to write an example on how to use wait() and notify(), but seems that the wait() can't be notified
public class Transfer {
private int[] data;
private volatile int ptr;
private final Object lock = new Object();
public Transfer(int[] data) {
this.data = data;
this.ptr = 0;
}
public void send() {
while (ptr < data.length) {
synchronized (lock) {
try {
System.out.println("-----wait");
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
ptr++;
}
}
}
public void receive() {
while (ptr < data.length) {
synchronized (lock) {
System.out.println("current is " + data[ptr]);
System.out.println("-----notify");
lock.notifyAll();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
////in main()
int[] data = new int[] { 111, 222, 333, 444, 555, 666, 777, 888, 999, 000 };
Transfer tf = new Transfer(data);
Thread t1 = new Thread(() -> {
tf.receive();
});
Thread t2 = new Thread(() -> {
tf.send();
});
t2.start();
t1.start();
but the result is :
-----wait
current is 111
-----notify
current is 111
-----notify
[endless repeat]
this is not what I expected, it should be :
current is 111
current is 222...
The problem with your code specifically is that you are keeping your locks way too long.
I'll first explain how wait/notify works, which is intricately connected with the concept of the monitor (synchronized), then how to do it right, and then as an encore, that you probably don't want to use this at all, it's too low level.
How does 'synchronized' work
When you write synchronized(x) you acquire the monitor - this operation can do one of three things. In all cases, x is a reference, so the reference is followed, it's about the object you find by following it.
If the reference is null, this immediately throws NPE.
If the object x points at has no current monitor, this thread becomes the monitor, the monitor count becomes 1, and code continues.
If the object x points at has a monitor but it is this thread, then the monitor count is incremented and code continues.
If the object x points at has a monitor but it is another thread, the thread will block until the monitor becomes available. Once it is available, some unfair dice show up, are rolled, and determine which of all threads 'fighting' to acquire the monitor will acquire it. Unfair in the sense that there are no guarantees made and the JVM is free to use any algorithm it wants to decide who 'wins'. If your code depends on fairness or some set order, your code is broken.
Upon reaching the } of the synchronized block, the monitor count is decremented. If it hits 0, the monitor is released (and the fight as per #4 starts, if other threads are waiting). In other words, locks are 're-entrant' in java. A thread can write synchronized(a){synchronized(a){}} and won't deadlock with itself.
Yes, this establishes comes-before stuff as per the Java Memory Model: Any fights arbitrated by a synchronized block will also ensure any writes by things that clearly came before (as established by who wins the fight) are observable by anything that clearly came after.
A method marked as 'synchronized' is effectively equivalent to wrapping the code in synchronized(this) for instance methods, and synchronized(MyClass.class) for static methods.
Monitors are not released and cannot be changed in java code* except via that } mechanism; (there is no public Thread getMonitor() {..} in j.l.Object or anywhere else) - in particular if the thread blocks for any other reason, including Thread.sleep, the monitor status does not change - your thread continues to hold on to it and thus stops all other threads from acquiring it. With one exception:
So how does wait/notify factor into this?
to wait/notify on x you MUST hold the monitor. this: x.notify();, unless it is wrapped in a synchronized(x) block, does not work.
When you wait(), the monitor is released, and the monitor count is remembered. a call to wait() requires 2 things to happen before it can continue: The 'wait' needs to be cancelled, either via a timeout, or an interrupt, or via a notify(All), and the thread needs to acquire that monitor again. If done normally (via a notify), by definition this is a fight, as whomever called notify neccessarily is still holding that monitor.
This then explains why your code does not work - your 'receiver' snippet holds on to the monitor while it sleeps. Take the sleep outside of the synchronized.
How do you use this, generally
The best way to use wait/notifyAll is not to make too many assumptions about the 'flow' of locking and unlocking. Only after acquiring the monitor, check some status. If the status is such that you need to wait for something to happen, then and only then start the wait() cycle. The thread that will cause that event to happen will first have to acquire the monitor and only then set steps to start the event. If this is not possible, that's okay - put in a failsafe, make the code that wait()s use a timeout (wait(500L) for example), so that if things fail, the while loop will fix the problem. Furthermore, there really is no good reason to ever use notify so forget that exists. notify makes no guarantees about what it'll unlock, and given that all threads that use wait ought to be checking the condition they were waiting for regardless of the behaviour of wait, notifyAll is always the right call to make.
So, it looks like this... let's say we're waiting for some file to exist.
// waiting side:
Path target = Paths.get("/file-i-am-waiting-for.txt");
synchronized (lock) {
while (!Files.isRegularFile(target)) {
try {
lock.wait(1000L);
} catch (InterruptedException e) {
// this exception occurs ONLY
// if some code explicitly called Thread.interrupt()
// on this thread. You therefore know what it means.
// usually, logging interruptedex is wrong!
// let's say here you intended it to mean: just exit
// and do nothing.
// to be clear: Interrupted does not mean:
// 'someone pressed CTRL+C' or 'the system is about to shutdown'.
return;
}
}
performOperation(target);
}
And on the 'file creation' side:
Path tgt = Paths.get("/file-i-am-waiting-for.txt");
Path create = tgt.getParent().resolve(tgt.getFileName() + ".create");
fillWithContent(create);
synchronized (lock) {
Files.move(create, tgt, StandardOpenOption.ATOMIC_MOVE);
lock.notifyAll();
}
The 'sending' (notifying) side is very simple, and note how we're using the file system to ensure that if the tgt file exists at all, it's fully formed and not a half-baked product. The receiving side uses a while loop: the notifying is itself NOT the signal to continue; it is merely the signal to re-check for the existence of this file. This is almost always how to do this stuff. Note also how all code involved with that file is always only doing things when they hold the lock, thus ensuring no clashes on that part.
But.. this is fairly low level stuff
The java.util.concurrent package has superior tooling for this stuff; for example, you may want a latch here, or a ReadWriteLock. They tend to outperform you, too.
But even juc is low level. Generally threading works best if the comm channel used between threads is inherently designed around concurrency. DBs (with a proper transaction level, such as SERIALIZABLE), or message buses like rabbitmq are such things. Why do you think script kiddies fresh off of an 8 hour course on PHP can manage to smash a website together that actually does at least hold up, thread-wise, even if it's littered with security issues? Because PHP enforces a model where all comms run through a DB because PHP is incapable of anything else in its basic deployment. As silly as these handcuffs may sound, the principle is solid, and can be applied just as easily from java.
*) sun.misc.Unsafe can do it, but it's called Unsafe for a reason.
Some closing best practices
Locks should be private; this is a rule broken by most examples and a lot of java code. You've done it right: if you're going to use synchronized, it should probably be on lock, which is private final Object lock = new Object();. Make it new Object[0] if you need it to be serializable, which arrays are, and Objects aren't.
if ever there is code in your system that does: synchronized(a) { synchronized (b) { ... }} and also code that odes: synchronized(b) { synchronized (a) { ... }} you're going to run into a deadlock at some point (each have acquired the first lock and are waiting for the second. They will be waiting forever. Be REAL careful when acquiring more than one monitor, and if you must, put in a ton of effort to ensure that you always acquire them in the same order to avoid deadlocks. Fortunately, jstack and such (tools to introspect running VMs) can tell you about deadlocks. The JVM itself, unfortunately, will just freeze in its tracks, dead as a doornail, if you deadlock it.
class Transfer {
private int[] data;
private volatile int ptr;
private final Object lock = new Object();
public Transfer(int[] data) {
this.data = data;
this.ptr = 0;
}
public void send() {
while (ptr < data.length) {
synchronized (lock) {
try {
System.out.println("-----wait");
lock.notifyAll();
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
ptr++;
}
}
}
public void receive() {
while (ptr < data.length) {
synchronized (lock) {
System.out.println("current is " + data[ptr]);
System.out.println("-----notify");
try {
lock.notifyAll();
lock.wait();
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
"Thread.sleep" does not release the lock. So you need "lock.wait" to release the lock and let other thread proceed. Then after "send" increment the pointer, it should also notify so that other thread who is stuck at receive can now proceed.
I have a thread sleep problem. Inside the thread run method i have a synchronized block, and a sleep time.
Each thread increments or decrements the shared class "value" in 5 units, and then sleeps.
public class borr {
public static void main(String[] args) {
int times=5;
int sleeptime=1000;
int initial=50;
Shared shared = new Shared(initial);
ThreadClass tIncrement = new ThreadClass(shared,times,sleeptime,true);
ThreadClass tDecrement = new ThreadClass(shared,times,sleeptime,false);
tIncrement.start();
tDecrement.start();
}
}
class Shared{
int value=0;
public Shared(int value) {
super();
this.value = value;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
}
class ThreadClass extends Thread{
Shared shared;
int times=0;
int sleeptime=0;
boolean inc;
public ThreadClass(Shared shared, int times, int sleeptime, boolean inc) {
super();
this.shared = shared;
this.times = times;
this.sleeptime = sleeptime;
this.inc = inc;
}
public void run() {
int aux;
if(inc) {
for(int i=0;i<times;i++) {
synchronized(shared) {
aux=shared.getValue()+1;
shared.setValue(aux);
System.out.println("Increment, new value"+shared.getValue());
try {
Thread.sleep(sleeptime);
}catch(Exception e) {
e.printStackTrace();
}
}
}
}
else {
for(int i=0;i<times;i++) {
synchronized(shared) {
aux=shared.getValue()-1;
shared.setValue(aux);
System.out.println("Decrement, new value"+shared.getValue());
try {
Thread.sleep(sleeptime);
}catch(Exception e) {
e.printStackTrace();
}
}
}
}
}
}
But if I move the Thread.sleep out of the synchronized block, like this, the output is increment, decrement, increment, decrement. When it stops sleeping and starts a new iteration of the loop, shouldn't the other thread try to enter? instead, it continues looping until that thread is finished:
for(int i=0;i<times;i++) {
synchronized(shared) {
aux=shared.getValue()-1;
shared.setValue(aux);
System.out.println("Decrement, new value"+shared.getValue());
}
try {
Thread.sleep(sleeptime);
}catch(Exception e) {
e.printStackTrace();
}
}
This is bad:
for(...) {
synchronized(some_lock_object) {
...
}
}
The reason it's bad is, Once some thread, A, gets into that loop, then every time it unlocks the lock, The very next thing it does is to lock the lock again.
If the loop body takes any significant amount of time to execute, then any other thread, B, that's waiting for the lock will be put into a wait state by the operating system. Each time thread A releases the lock, thread B will start to wake up, but thread A will be able to re-acquire it before thread B gets a chance.
This is a classic example of starvation.
One way around the problem would be to use a ReentrantLock with a fair ordering policy instead of using a synchronized block. When threads compete for a fair lock, the winner always is the one that's been waiting the longest.
But, fair locks are expensive to implement. A far better solution is to always keep the body of any synchronized block as short and as sweet as possible. Usually, a thread should keep a lock locked for no longer than it takes to assign a small number of fields in some object.
In variant A you use two threads that ...
repeat 5 times
enter a sync block
increment
wait 1 second
repeat 5 times
enter a sync block
decrement
wait 1 second
In variant B you use two threads that ...
repeat 5 times
enter a sync block
increment
wait 1 second
repeat 5 times
enter a sync block
decrement
wait 1 second
In variant A both threads are active (= stay in a sync block) all the time.
In variant B both threads are sleeping most of the time.
As there is absolutely no guarantee which threads are executed next, it is not surprising that variant A and B behave so differently. While in A both threads could - in theory - be active in parallel, the second thread has not much chance to be active as not being in a synchronization context does not guarantee that a context switch is performed at that moment (and another thread is run). In variant B that is completely different: As both threads sleep most of the time, the runtime environment has no other chance as running another thread while one is sleeping. A sleep will trigger switching to another thread as the VM tries to make the best of existing CPU resources.
Nevertheless: The result AFTER both threads have been run will be exactly the same. This is the only determinism you can rely on. Everything else depends on specific implementation details how the VM will handle threads and synchronizations blocks and can even vary from OS to OS or one implementation of a VM to another.
But if i move the Thread.sleep out of the synchronized block, like this, the output is increment, decrement, increment, decrement. The sleep is still inside each iteration of the loop so, shouldnt the result be the same in both cases?:
when it stops sleeping and starts a new iteration of the loop, shouldn't the other thread try to enter.
They both try to enter.
And the other one is already in a wait status (i.e. not actively running) because it tried to enter before. Whereas the thread that has just released the lock can run on and get the now uncontested lock right back.
This is a race condition. When both threads want the lock at the same time, the system is free to choose one. It seems it picks the one that a few instructions ago just released it. Maybe you can change this by yield()ing. Maybe not. But either way, it is not specified/deterministic/fair. If you care about execution order, you need to explicitly schedule things yourself.
I have written below class to understand SemaPhore. However the result is unexpected. I couldn't understand actual work of SemaPhore. How it is used as a lock, signaling and for counting?
public class TrySemaPhore
{
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(10);
Semaphore semaphore = new Semaphore(2);
Runnable newTask= () -> {
boolean permit = false;
try {
permit = semaphore.tryAcquire();
if(permit)
System.out.println("doing work");
} finally {
if(permit){
semaphore.release();
System.out.println("Work done!!");
}
}
};
for(int i=0; i<=4; i++){
executor.submit(newTask);
}
stop(executor);
}
private static void stop(ExecutorService executor) {
/*code to stop executor*/
}
}
Result
doing work
Work done!!
doing work
Work done!!
doing work
Work done!!
doing work
Work done!!
doing work
Work done!!
I have 10 Fixed number of Threads. I have 5 different tasks(for loop) which needs to complete. I have Semaphore with 2 permits. I want to understand Semaphore and it's benefit in a very simple way (not like theory available through googling).
A counting semaphore. Conceptually, a semaphore maintains a set of
permits. Each acquire blocks if necessary until a permit is
available, and then takes it. Each release adds a permit,
potentially releasing a blocking acquirer.
Before obtaining an item each thread must acquire a permit from
the semaphore, guaranteeing that an item is available for use. When
the thread has finished with the item it is returned back to the
pool and a permit is returned to the semaphore, allowing another
thread to acquire that item. Note that no synchronization lock is
held when acquire is called as that would prevent an item
from being returned to the pool. The semaphore encapsulates the
synchronization needed to restrict access to the pool, separately
from any synchronization needed to maintain the consistency of the
pool itself.
Use case:
1.An unbounded queue requires one semaphore, (to count the queue entries), and a mutex-protected thread-safe queue, (or equivalent lock-free thread-safe queue). The semaphore is intialized to zero. Producers lock the mutex, push an object onto the queue, unlock the mutex and signal the semaphore. Consumers wait on the semaphore, lock the mutex, pop the object and unlock the mutex.
2.Object pool where you can restrict the number of resource using semaphore .Multiple thread try to acquire the object in the pool and you have limited number of object then some thread will wait until some thread releases.
class Pool {
private static final int MAX_AVAILABLE = 100;
private final Semaphore available = new Semaphore(MAX_AVAILABLE, true);
public Object getItem() throws InterruptedException {
available.acquire();
return getNextAvailableItem();
}
public void putItem(Object x) {
if (markAsUnused(x))
available.release();
}
want to know what is deadlock condition in threads, because in many of the books i studied how to avoid deadlock situation, i just want to know what is deadlock situation and a example code for that?
Deadlock is a situation that a concurrent program cannot proceed.
A thread is waiting for another
thread, while the other thread is
waiting for the first thread's
completion.
The commonly used real world example is a traffic flow.
No traffic can move until the other queue moves.
You may find a good discussion on deadlocks here.
Update : This is one java example I found on web (Oreilly book). It has comments on that so you can understand it easily.
Dining Philosophers problem is another good example to understand the deadlocks.
removed dead Imageshack link
Dead lock detection and Deadlock prevention are two of related areas that might be useful while learning about the deadlocks.
Deadlock is when A waits on B and B waits on A.
So you could have in thread A:
while(B.incomplete()){
B.wait();
} A.complete = true;
and have in thread B:
while(A.incomplete()){
A.wait();
} B.complete = true;
Here's an example of a deadlock that doesn't use wait. As long as you've got synchronization, there's a potential for deadlock.
public class Deadlock {
static class Deadlocker {
private Deadlocker other;
public void setOther(Deadlocker other) {
this.other = other;
}
synchronized void doSomethingWithOther() {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
}
other.doSomething();
}
synchronized void doSomething() {
}
}
public static void main(String[] args) {
final Deadlocker d1 = new Deadlocker();
final Deadlocker d2 = new Deadlocker();
d1.setOther(d2);
d2.setOther(d1);
Thread t1 = new Thread() {
public void run() {
d1.doSomethingWithOther();
}
};
Thread t2 = new Thread() {
public void run() {
d2.doSomethingWithOther();
}
};
t1.start();
t2.start();
}
}
The deadlock occurs when t1 is in d1.doSomethingWithOther() (and hence has a lock on d1) and t2 is in d2.doSomethingWithOther() (and hence has a lock on d2). When each thread tries to call doSomething() on the object the other thread has a lock on, they end up stuck, waiting for each other.
Note that a deadlock doesn't necessarily involve only two threads. It's possible to have a cycle of any size. Worse, once a deadlock has occurred, any other thread that attempts to obtain a lock that a deadlocked thread is already holding will end up becoming effectively deadlocked itself, even without being in the cycle.
Deadlock is caused by resource contention that is not directly solvable without some sort of resource control (such as a graph cycle which relies on two resource locks).
One of the most common (and generally used for illustration) deadlock scenarios is lock inversion:
Consider an application which has two critical resources (resA, resB), and two locks (lockA, lockB). Each resource is protected by the corresponding lock (resA => lockA, resB => lockB).
Two resources are contending for the resources, Thread A reserves lockA (and thus resource A) and then is suspended for a context switch) before being able to reserve lockB. Thread B receives control, reserves lockB and then attempts to reserve lockA. This causes the thread to be suspended and control returned back to Thread A, who is waiting on lockB, which is held be Thread B.
In this scenario you will have a deadlock because of a cyclic dependency between the two threads on the two contended resources (lockA and lockB) which cannot be resolved without separate intervention.
This can be trivially resolved by either:
Ensuring the two locks are resolved in order (not the best choice)
Only holding one lock for each critical section at a time (i.e. release lockA before attempting to acquire lockB)
Imagine the following threads of logic.
In catch-22, the novel,
the fighter pilot was to be grounded due to insanity. He could prove against the case of insanity by saying he was not insane so that he could fly again. But by asking, wanting to fly into battle to endanger his life would demonstrate that he is crazy.
North Korea wants the G7 to deliver economic aid before stopping uranium refinement. The US and Japan says "No Way, because they would renege after getting the aid."
System reboot conflict.
The system would not shut down until
all user processes have been
terminated.
The editor, a user process would not
terminate unless the edit has been
saved.
The edit cannot be saved unless the
usb drive is present because the
editor executable was called from
the usb drive.
The usb drive was dismounted because
of a driver upgrade. The usb drive
could not be mounted until the
system is shut down and rebooted.
The Android robot has prime directives
A robot may not injure a human being or, through inaction, allow a human being to come to harm.
A robot must obey any orders given to it by human beings, except where such orders would conflict with the First directive.
A robot must protect its own existence as long as such protection does not conflict with the First or Second directive.
The human occupants of the base sent robot to retrieve a radio-active power source. Without the power source, the base would shut down and the human colony would die. But the robot discovers that the power source is so powerful and unshielded, handling it would cause the robot to malfunction and become a danger to the human colony.
DeadLock is a situation when first thread is waiting for second Thread,
while Second Thread is waiting for first thread's completion.
See this Traffic Deadlock to better UnderStand DeadLock situation
**Java Code Demo**
public class DeadLockDemo
{
public static Object object1 = new Object();
public static Object object2 = new Object();
private int index;
public static void main(String[] a) {
Thread t1 = new Thread1();
Thread t2 = new Thread2();
t1.start();
t2.start();
}
private static class Thread1 extends Thread {
public void run() {
synchronized (object1) {
System.out.println("Thread 1: Holding lock 1...");
try { Thread.sleep(10); }
catch (InterruptedException e) {}
System.out.println("Thread 1: Waiting for lock 2...");
synchronized (object2) {
System.out.println("Thread 2: Holding lock 1 & 2...");
}
}
}
}
private static class Thread2 extends Thread {
public void run() {
synchronized (object2) {
System.out.println("Thread 2: Holding lock 2...");
try { Thread.sleep(10); }
catch (InterruptedException e) {}
System.out.println("Thread 2: Waiting for lock 1...");
synchronized (object1) {
System.out.println("Thread 2: Holding lock 2 & 1...");
}
}
}
}
}
A deadlock is when two (or more) threads are each waiting for the other to finish. Thread A cannot complete until thread B does something, and thread B cannot finish until thread A does something else.
Threads deadlock when waiting on each
other to release some resources, but
by performing that blocking wait,
they're not releasing the resources
the other threads need in order to
unblock. The threads can't make any
progress until the resources are
released, but because they're not
making progress, the resources will
never be released, the threads are
locked up, and thus "deadlock."
A nice article by Stephen Toub might help you a bit.