Deadlock in a single threaded java program [duplicate]
Read that deadlock can happen in a single threaded java program. I am wondering how since there won't be any competition after all. As far as I can remember, books illustrate examples with more than one thread. Can you please give an example if it开发者_如何学C can happen with a single thread.
It's a matter of how exactly you define "deadlock".
For example, this scenario is somewhat realistic: a single-threaded application that uses a size-limited queue that blocks when its limit is reached. As long as the limit is not reached, this will work fine with a single thread. But when the limit is reached, the thread will wait forever for a (non-existing) other thread to take something from the queue so that it can continue.
Before multicore processors became cheap, all desktop computers had single-core processors. Single-core processors runs only on thread. So how multithreading worked then? The simplest implementation for Java would be:
thread1's code:
doSomething();
yield(); // may switch to another thread
doSomethingElse();
thread2's code:
doSomething2();
yield(); // may switch to another thread
doSomethingElse2();
This is called cooperative multithreading - all is done with just 1 thread, and so multithreading was done in Windows 3.1.
Today's multithreading called preemptive multithreading is just a slight modification of cooperative multithreading where this yield() is called automatically from time to time.
All that may reduce to the following interlacings:
doSomething();
doSomething2();
doSomethingElse2();
doSomethingElse();
or:
doSomething();
doSomething2();
doSomethingElse();
doSomethingElse2();
And so on... We converted multithreaded code to single-threaded code. So yes, if a deadlock is possible in multithreaded programs in single-threaded as well. For example:
thread1:
queue.put(x);
yield();
thread2:
x = queue.waitAndGet()
yield();
It's OK with this interlace:
queue.put(x);
x = queue.waitAndGet()
But here we get deadlock:
x = queue.waitAndGet()
queue.put(x);
So yes, deadlocks are possible in single-threaded programs.
Well I dare say yes
If you try to acquire the same lock within the same thread consecutively, it depends on the type of lock or locking implementation whether it checks if the lock is acquired by the same thread. If the implementation does not check this, you have a deadlock.
For synchronized this is checked, but I could not find the guarantee for Semaphore.
If you use some other type of lock, you have to check the spec as how it is guaranteed to behave!
Also as has already been pointed out, you may block (which is different from deadlock) by reading/ writing to a restricted buffer. For instance you write things into a slotted buffer and only read from it on certain conditions. When you can no longer insert, you wait until a slot becomes free, which won't happen since you yourself do the reading.
So I daresay the answer should be yes, albeit not that easy and usually easier to detect.
hth
Mario
Even if your java stuff is single-threaded there are still signal handlers, which are executed in a different thread/context than the main thread.
So, a deadlock can indeed happen even on single-threaded solutions, if/when java is running on linux.
QED. -pbr
No, Sounds pretty impossible to me.
But you could theoretically lock a system resource while another app locks another that you're going to request and that app is going to request the one you've already locked. Bang Deadlock.
But the OS should be able to sort this thing out by detecting that and give both resources to one app at the time. Chances for this to happen is slim to none, but any good OS should be able to handle this one-in-a billion chance.
If you make the design carefully and only locks one resource at a time, this can not happen.
No.
Deadlock is a result of multiple threads (or processes) attempting to acquire locks in such a way that neither can continue.
Consider a quote from the Wikipedia article: (http://en.wikipedia.org/wiki/Deadlock)
"When two trains approach each other at a crossing, both shall come to a full stop and neither shall start up again until the other has gone."
It is actually quite easy:
BlockingQueue bq = new ArrayBlockingQueue(1);
bq.take();
will deadlock.
精彩评论