public class MainLock {
public static void main(String[] args) throws Exception {
LockClass lock = new LockClass();
Thread t1 = new Thread(new Runnable() {
#Override
public void run() {
lock.incrementa();
}
});
Thread t2 = new Thread(new Runnable() {
#Override
public void run() {
lock.incrementb();
}
});
Thread t3 = new Thread(new Runnable() {
#Override
public void run() {
lock.incrementa();
}
});
t1.start();
t2.start();
t3.start();
}
}
public class LockClass {
int a;
int b;
ReentrantLock lock = new ReentrantLock();
public void incrementa() {
lock.lock();
try {
for (int i = 0; i < 3; i++) {
System.out.println("a " + a++);
Thread.sleep(1000);
}
lock.unlock();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void incrementb() {
try {
lock.lock();
for (int i = 0; i < 3; i++) {
System.out.println("b " + b++);
Thread.sleep(1000);
}
lock.unlock();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
The output above result is
a0 a1 a2 b0 b1 b2 a3 a4 a5
I want to achieve a0 b0 a1 b1 a2 b2 a3 a4 a5, thread t1 and t2 should run parallely and t3 should be blocked because of lock by t1.
I know using static synchronization in incrementb() will work but I am looking something only with locks.
I am looking for Method level locking, not object level or class level
I there any way in java to achieve this.
I am looking something only with locks
That's not what locks are for. Pretty much the only thing you should use locks* for is to ensure safe access to shared variables. You should not try to use locks for signaling between threads.
I want to achieve a0 b0 a1 b1 a2 b2...
The best way to make certain things happen in a certain order is to do all of those things in the same thread. You can make threads take turns like that, but it completely defeats the purpose of using threads. The purpose of using threads is to allow different parts of a program to run concurrently, and that is exactly what you are not allowing the threads to do when you force them to take turns.
If you really want to make the threads take turns (e.g., if this is a homework assignment**) then IMO the best way to do that is to pass a virtual token from thread to thread. Holding the token means, "it's your turn."
One way to do it is to use Semaphore objects: Make one semaphore per thread, but give each thread a reference to two of them. Each thread will use one semaphore to receive the token, and the other semaphore to pass the token off to the next thread:
class MyRunnable {
private Semaphore token_in;
private Semaphore token_out;
public MyRunnable(Semaphore token_in, Semaphore token_out) {
this.token_in = token_in;
this.token_out = token_out;
}
public void Run() {
while (...thread should keep running...) {
token_in.acquire(); // wait to receive the token.
...do stuff...
token_out.release(); // hand the token to the next thread.
}
}
}
When you start this up, you must make sure that each thread's token_out is the next thread's token_in:
static void main(...) {
int TOKEN = 1;
int EMPTY = 0;
Semaphore s1 = new Semaphore(TOKEN);
Semaphore s2 = new Semaphore(EMPTY);
Semaphore s3 = new Semaphore(EMPTY);
MyRunnable r1 = new MyRunnable(s1, s2);
MyRunnable r2 = new MyRunnable(s2, s3);
MyRunnable r3 = new MyRunnable(s3, s1);
...create and start the three threads for r1, r2, and r3...
}
* "Locks" includes any use of a synchronized block or a synchronized method or a ReentrantLock.
** If you want to tell your instructor what I said about making threads take turns, that's up to you. You'd be doing the world a favor if you can help eradicate this assignment, but only you can decide whether it's politically smart to talk to your instructor about ideas that are above the level of what they're teaching.
Related
I have a timer that will create a new thread and wait for the timer to expire before calling the notify function. It works correctly during the first execution, but when the timer is started a second time, an exception is thrown trying to create the new thread. The debug output shows that the previous thread has exited before attempting to create the new thread.
Timer.hpp:
class TestTimer
{
private:
std::atomic<bool> active;
int timer_duration;
std::thread thread;
std::mutex mtx;
std::condition_variable cv;
void timer_func();
public:
TestTimer() : active(false) {};
~TestTimer() {
Stop();
}
TestTimer(const TestTimer&) = delete; /* Remove the copy constructor */
TestTimer(TestTimer&&) = delete; /* Remove the move constructor */
TestTimer& operator=(const TestTimer&) & = delete; /* Remove the copy assignment operator */
TestTimer& operator=(TestTimer&&) & = delete; /* Remove the move assignment operator */
bool IsActive();
void StartOnce(int TimerDurationInMS);
void Stop();
virtual void Notify() = 0;
};
Timer.cpp:
void TestTimer::timer_func()
{
auto expire_time = std::chrono::steady_clock::now() + std::chrono::milliseconds(timer_duration);
std::unique_lock<std::mutex> lock{ mtx };
while (active.load())
{
if (cv.wait_until(lock, expire_time) == std::cv_status::timeout)
{
lock.unlock();
Notify();
Stop();
lock.lock();
}
}
}
bool TestTimer::IsActive()
{
return active.load();
}
void TestTimer::StartOnce(int TimerDurationInMS)
{
if (!active.load())
{
if (thread.joinable())
{
thread.join();
}
timer_duration = TimerDurationInMS;
active.store(true);
thread = std::thread(&TestTimer::timer_func, this);
}
else
{
Stop();
StartOnce(TimerDurationInMS);
}
}
void TestTimer::Stop()
{
if (active.load())
{
std::lock_guard<std::mutex> _{ mtx };
active.store(false);
cv.notify_one();
}
}
The error is being thrown from my code block here:
thread = std::thread(&TestTimer::timer_func, this);
during the second execution.
Specifically, the error is being thrown from the move_thread function: _Thr = _Other._Thr;
thread& _Move_thread(thread& _Other)
{ // move from _Other
if (joinable())
_XSTD terminate();
_Thr = _Other._Thr;
_Thr_set_null(_Other._Thr);
return (*this);
}
_Thrd_t _Thr;
};
And this is the exception: Unhandled exception at 0x76ED550B (ucrtbase.dll) in Sandbox.exe: Fatal program exit requested.
Stack trace:
thread::move_thread(std::thread &_Other)
thread::operator=(std::thread &&_Other)
TestTimer::StartOnce(int TimerDurationInMS)
If it's just a test
Make sure the thread handler is empty or joined when calling the destructor.
Make everything that can be accessed from multiple threads thread safe (specifically, reading the active flag). Simply making it an std::atomic_flag should do.
It does seem like you are killing a thread handle pointing to a live thread, but hard to say without seeing the whole application.
If not a test
...then generally, when need a single timer, recurreing or not, you can just go away with scheduling an alarm() signal into itself. You remain perfectly single threaded and don't even need to link with the pthread library. Example here.
And when expecting to need more timers and stay up for a bit it is worth to drop an instance of boost::asio::io_service (or asio::io_service if you need a boost-free header-only version) into your application which has mature production-ready timers support. Example here.
You create the TestTimer and run it the first time via TestTimer::StartOnce, where you create a thread (at the line, which later throws the exception). When the thread finishes, it sets active = false; in timer_func.
Then you call TestTimer::StartOnce a second time. As active == false, Stop() is not called on the current thread, and you proceed to creating a new thread in thread = std::thread(&TestTimer::timer_func, this);.
And then comes the big but:
You have not joined the first thread before creating the second one. And that's why it throws an exception.
I am working on a c++ (11) project and on the main thread, I need to check the value of two variables. The value of the two variables will be set by other threads through two different callbacks. I am using two condition variables to notify changes of those two variables. Because in c++, locks are needed for condition variables, I am not sure if I should use the same mutex for the two condition variables or I should use two mutex's to minimize exclusive execution. Somehow, I feel one mutex should be sufficient because on one thread(the main thread in this case) the code will be executed sequentially anyway. The code on the main thread that checks (wait for) the value of the two variables wont be interleaved anyway. Let me know if you need me to write code to illustrate the problem. I can prepare that. Thanks.
Update, add code:
#include <mutex>
class SomeEventObserver {
public:
virtual void handleEventA() = 0;
virtual void handleEventB() = 0;
};
class Client : public SomeEventObserver {
public:
Client() {
m_shouldQuit = false;
m_hasEventAHappened = false;
m_hasEventBHappened = false;
}
// will be callbed by some other thread (for exampe, thread 10)
virtual void handleEventA() override {
{
std::lock_guard<std::mutex> lock(m_mutexForA);
m_hasEventAHappened = true;
}
m_condVarEventForA.notify_all();
}
// will be called by some other thread (for exampe, thread 11)
virtual void handleEventB() override {
{
std::lock_guard<std::mutex> lock(m_mutexForB);
m_hasEventBHappened = true;
}
m_condVarEventForB.notify_all();
}
// here waitForA and waitForB are in the main thread, they are executed sequentially
// so I am wondering if I can use just one mutex to simplify the code
void run() {
waitForA();
waitForB();
}
void doShutDown() {
m_shouldQuit = true;
}
private:
void waitForA() {
std::unique_lock<std::mutex> lock(m_mutexForA);
m_condVarEventForA.wait(lock, [this]{ return m_hasEventAHappened; });
}
void waitForB() {
std::unique_lock<std::mutex> lock(m_mutexForB);
m_condVarEventForB.wait(lock, [this]{ return m_hasEventBHappened; });
}
// I am wondering if I can use just one mutex
std::condition_variable m_condVarEventForA;
std::condition_variable m_condVarEventForB;
std::mutex m_mutexForA;
std::mutex m_mutexForB;
bool m_hasEventAHappened;
bool m_hasEventBHappened;
};
int main(int argc, char* argv[]) {
Client client;
client.run();
}
i am using semaphore for thread communication i have two threads one is OddThread and another is EvenThread ,i am printing value from 1 to 10 OddThread will print only odd numbers between 1 to 10 and EvenThread thread is printing only even numbers between 1 to 10. for that i have used semaphore for threads to communicate properly .what is actually happening is that OddThread is printing only 1 and EvenThread only 2 and then both get stopped. I am not under standing what is actually happening.can any body suggest.
public class ThreadProducerConsumerSemaphore {
/**
* #param args
*/
public static void main(String[] args) {
Semaphore p = new Semaphore(1);
Semaphore c = new Semaphore(0);
OddThread producer = new OddThread(p, c);
EvenThread consumer = new EvenThread(p, c);
Thread t1 = new Thread(producer, "Thread producer");
Thread t2 = new Thread(consumer, "Thread consumer");
t1.start();
t2.start();
}
}
class OddThread implements Runnable {
Semaphore p;
Semaphore c;
public OddThread(Semaphore p, Semaphore c) {
super();
this.p = p;
this.c = c;
}
int counter = 1;
#Override
public void run() {
while (true) {
try {
p.acquire(1);
System.out.println(Thread.currentThread().getName() + " "
+ counter);
if (counter == 10) {
break;
}
counter++;
c.release(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
class EvenThread implements Runnable {
Semaphore p;
Semaphore c;
int counter = 2;
public EvenThread(Semaphore p, Semaphore c) {
super();
this.p = p;
this.c = c;
}
#Override
public void run() {
while (true) {
try {
c.acquire(1);
System.out.println(Thread.currentThread().getName() + " "
+ counter);
if (counter == 10) {
break;
}
counter=counter+2;
p.acquire(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
Your code can't be correct, it's not even symmetrical.
p.acquire(1);
c.release(1);
c.acquire(1);
p.acquire(1);
Your EvenThread.run method acquires both c and p, rather than releasing one of them.
Note, however, that your code doesn't look like it'll exit properly even once it's been fixed. Consider: neither thread releases a semaphore before it exits, so one of the threads will inevitably be blocked.
here is your problem:
............
c.acquire(1);
System.out.println(Thread.currentThread().getName() + " "
+ counter);
if (counter == 10) {
break;
}
counter=counter+2;
p.acquire(1); <--deadlock this has already been acquired by the other thread.
..............
you should release p here, to allow the other thread to continue; so replace the line I indicated with p.release(1) and it should be fine.
I have a class ChunkManager that has a few (supposed to be) asynchronous methods. These methods handle tasks in my game engine such as loading the map blocks (similar to Minecraft) on a different thread so as not to completely halt the main thread (they are lengthy operations)
Here is one of those methods:
void ChunkManager::asyncRenderChunks(){
boost::thread loadingThread(&ChunkManager::renderChunks,this);
}
Where renderChunks looks like:
void ChunkManager::renderChunks(){
activeChunksMutex->lock();
for(int z=0; z < CHUNK_MAX; z=z+1)
{
for(int y=0; y < CHUNK_MAX; y=y+1)
{
for(int x=0; x < CHUNK_MAX; x=x+1)
{
activeChunks[x][y][z]->Render(scnMgr);
}
}
}
activeChunksMutex->unlock();
}
This should work, right? However it crashes when this runs. I have a feeling it has to do with what I do with the thread after it's created, because if I put
loadingThread.join();
in the aforementioned method, it works fine, but the main thread is halted because obviously its just waiting for the new thread to finish, effectively bringing me back to square one.
Any advice?
Sorry if this is a retarded question, I am new to the concept of threads.
Thanks.
Update (4/9/2013):
I found this gem: http://threadpool.sourceforge.net/
..and solved my problem!
If you can join the thread, it must be joinable.
As it says in the documentation:
When the boost::thread object that represents a thread of execution is destroyed the program terminates if the thread is joinable.
You created a local thread object and immediately let it go out of scope: it is destroyed when ChunkManager::asyncRenderChunks returns.
Either:
make it a detached (non-joinable) thread
void ChunkManager::asyncRenderChunks() {
boost::thread loadingThread(&ChunkManager::renderChunks,this);
loadingThread.detach();
}
or create the thread object elsewhere and keep it alive
class ChunkManager {
boost::thread renderingThread;
bool renderChunkWork; // work to do flag
Chunk activeChunks[CHUNK_MAX][CHUNK_MAX][CHUNK_MAX];
boost::mutex activeChunksMutex;
boost::condition_variable activeChunksCV;
bool shutdown; // shutdown flag
void renderChunks() {
for(int z=0; z < CHUNK_MAX; ++z)
for(int y=0; y < CHUNK_MAX; ++y)
for(int x=0; x < CHUNK_MAX; ++x)
activeChunks[x][y][z]->Render(scnMgr);
}
void renderChunkThread() {
boost::unique_lock<boost::mutex> guard(activeChunksMutex);
while (true) {
while (!(renderChunkWork || shutdown))
activeChunksCV.wait(guard);
if (shutdown)
break;
renderChunks();
doRenderChunks = false;
}
}
public:
ChunkManager()
: loadingThread(&ChunkManager::renderChunkThread, this),
renderChunkWork(false), shutdown(false)
{}
~ChunkManager() {
{ // tell the rendering thread to quit
boost::unique_lock<boost::mutex> guard(activeChunksMutex);
renderChunkShutdown = true;
activeChunksCV.notify_one();
}
renderingThread.join()
}
void asyncRenderChunks() {
boost::unique_lock<boost::mutex> guard(activeChunksMutex);
if (!renderChunkWork) {
renderChunkWork = true;
activeChunksCV.notify_one();
}
}
};
NB. In general, creating threads on-the-fly is less good than creating your threads up-front, and just waking them when there's something to do. It avoids figuring out how to handle a second call to asyncRenderChunks before the last one is complete (start a second thread? block?), and moves the latency associated with thread creation.
Note on object lifetime
It's important to realise that in this code:
void ChunkManager::asyncRenderChunks() {
SomeType myObject;
}
the instance myObject will be created and then immediately destroyed.
It crashes, because in the current version of Boost.Thread, you have to either join() a thread or detach() it - otherwise ~thread would terminate the program. (In earlier versions ~thread used to call detach() automatically.)
So if you don't want to join the thread - just detach it:
boost::thread loadingThread(&ChunkManager::renderChunks,this);
loadingThread.detach();
Hej,
I know how to pass parameters to a Runnable. But when my Thread has run, how to get the result of the process?
class Some implements Runnable
{
int p;
int endresult = 0;
public Some(int param){
p = param;
}
public void run(){
//do something
endresult += p;
//Now how to let the method who executed this runnable know that the result is 2;
}
}
Some s = new Some(1);
Thread t = new Thread(s);
t.start();
when t is finished i want to get the 'endresult' variable;
You have to wait for your thread to terminate and then you can get the field value directly:
t.join();
y = s.endresult;
declare endresult volatile and invoke t.join after it was started - when t is finished this will get the 'endresult' value