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.
Related
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.
Volatile provides reading and writing to program memory bypassing cache. We should use volatile when there is a common resource, such as an integer variable
So, I did a little experiment.
First I had the following classes:
public class Main3 {
static int j = 0;
public static void main(String[] args) throws InterruptedException {
new Thread1().start();
new Thread2().start();
}
static int i = 0;
static class Thread1 extends Thread{
#Override
public void run() {
while(i<5){
System.out.println("thread1 i = "+i);
i++;
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
static class Thread2 extends Thread{
#Override
public void run() {
int val = i;
while(val<5){
if(val!=i) {
System.out.println("thread2 i = " + i);
val = i;
}
}
}
}
}
In the first thread, the variable changes its value. The second thread monitors the change and displays the text on the console if it happened
i variable is a shared resource. And without volatile the program prints what was expected and cant :
thread1 i = 0
thread1 i = 1
thread1 i = 2
thread1 i = 3
thread1 i = 4
But, if i make this (add sleep to Thread2 class):
static class Thread2 extends Thread{
#Override
public void run() {
int val = i;
while(val<5){
if(val!=i) {
System.out.println("thread2 i = " + i);
val = i;
}
try {
sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
the program prints this and successfully finished:
thread1 i = 0
thread2 i = 1
thread1 i = 1
thread2 i = 2
thread1 i = 2
thread2 i = 3
thread1 i = 3
thread2 i = 4
thread1 i = 4
thread2 i = 5
So, if threads cache values, then why does sleep caching disappear with the advent of sleep?
I run the following code, when I use jstack check thread information, found 100 threads in the runnable state. I know what is the maximum number of CPU thread of execution core * 2, but I'm very confused, even jstack is not instantaneous, why is a runnable thread?Or is not executed by the CPU thread state is runnable.
Has not been thread of execution, his status is also a runnable?
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
new Thread(() -> {
long last = System.currentTimeMillis();
try {
byte[] buf = new byte[1024];
FileInputStream fileInputStream = new FileInputStream("");
while (fileInputStream.read(buf) != -1) {
}
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("read over " + (System.currentTimeMillis() - last) );
}, "name" + i).start();
}
}
I am develeping an application that uses a threadpool, submits tasks to it and synchronizes them. The main thread has to wait until all the submitted tasks from a single loop iteration finish and then it submits another bunch of tasks (because the tasks from the next iteration operate on the same data and they will be dependent on one another).
My question is, what is the best way to do that?
So far, what I have come up with is that each thread, after finishing a task, increments an atomic unsigned integer. When the integer equals the number of submitted tasks, the main thread continues its work and submits another round of tasks.
This is my first multithreaded application.
Is this an optimal and sensible way of dealing with this problem.
I'm using a threadpool class copied from an excellent book "C++ Concurrency in Action: by Anthony Williams.
Here are the classes:
class thread_pool
{
std::atomic_bool done;
thread_safe_queue<std::function<void()> > work_queue;
std::vector<std::thread> threads;
join_threads joiner;
void worker_thread()
{
while(!done)
{
std::function<void()> task;
if(work_queue.try_pop(task))
{
task();
}
else
{
std::this_thread::yield();
}
}
}
public:
thread_pool():
done(false),joiner(threads)
{
unsigned const thread_count=std::thread::hardware_concurrency();
try
{
for(unsigned i=0;i<thread_count;++i)
{
threads.push_back(
std::thread(&thread_pool::worker_thread,this));
}
}
catch(...)
{
done=true;
throw;
}
}
~thread_pool()
{
done=true;
}
template<typename FunctionType>
void submit(FunctionType f)
{
work_queue.push(std::function<void()>(f));
}
};
template<typename T>
class threadsafe_queue
{
private:
mutable std::mutex mut;
std::queue<T> data_queue;
std::condition_variable data_cond;
public:
threadsafe_queue()
{}
void push(T new_value)
{
std::lock_guard<std::mutex> lk(mut);
data_queue.push(std::move(new_value));
data_cond.notify_one();
}
void wait_and_pop(T& value)
{
std::unique_lock<std::mutex> lk(mut);
data_cond.wait(lk, [this]{return !data_queue.empty(); });
value = std::move(data_queue.front());
data_queue.pop();
}
std::shared_ptr<T> wait_and_pop()
{
std::unique_lock<std::mutex> lk(mut);
data_cond.wait(lk, [this]{return !data_queue.empty(); });
std::shared_ptr<T> res(
std::make_shared<T>(std::move(data_queue.front())));
data_queue.pop();
return res;
}
bool try_pop(T& value)
{
std::lock_guard<std::mutex> lk(mut);
if (data_queue.empty())
return false;
value = std::move(data_queue.front());
data_queue.pop();
}
std::shared_ptr<T> try_pop()
{
std::lock_guard<std::mutex> lk(mut);
if (data_queue.empty())
return std::shared_ptr<T>();
std::shared_ptr<T> res(
std::make_shared<T>(std::move(data_queue.front())));
data_queue.pop();
return res;
}
bool empty() const
{
std::lock_guard<std::mutex> lk(mut);
return data_queue.empty();
}
};
The main() function:
std::condition_variable waitForThreads;
std::mutex mut;
std::atomic<unsigned> doneCount = 0;
unsigned threadCount = 4; // sample concurrent thread count that I use for testing
void synchronizeWork()
{
doneCount++;
if (doneCount.load() == threadCount)
{
doneCount = 0;
std::lock_guard<std::mutex> lock(mut);
waitForThreads.notify_one();
}
}
void Task_A()
{
std::cout << "Task A, thread id: " << std::this_thread::get_id() << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(3000));
synchronizeWork();
}
int main()
{
unsigned const thread_count = std::thread::hardware_concurrency();
thread_pool threadPool;
for (int i = 0; i < 1000; ++i)
{
for (unsigned j = 0; j < thread_count; j++)
threadPool.submit(Task_A);
// Below is my way of synchronizing the tasks
{
std::unique_lock<std::mutex> lock(mut);
waitForThreads.wait(lock);
}
}
I am not familiar with the threadpool class you are using.
Without using such a class, the usual way to do this looks like this:
std::cout << "Spawning 3 threads...\n";
std::thread t1 (pause_thread,1);
std::thread t2 (pause_thread,2);
std::thread t3 (pause_thread,3);
std::cout << "Done spawning threads. Now waiting for them to join:\n";
t1.join();
t2.join();
t3.join();
std::cout << "All threads joined!\n";
I would imagine that any decent threadpool class would allow you to the same sort of thing, even more simply, by giving you a metho to block until all the threads have completed. I suggest you double check the documentation.
I am using Qt to generate a Window. Additionally I use libnfc to get access to a nfc reader, so far so good.
In my self written nfc-class i generate a new thread, this thread is polling for new tags on the reader. If there is a new tag, the thread will start a signal event for the MainWindow.
In the main window I have just a QWebView which will show different websites on different states (after start, new tag, tag removed), just realy basic stuff.
My problem is now: that the main window (or the QWebView) is not updating. If i switch to another programm and go back to my app, the window will be updated. I was already searching with google and trying different stuff but nothing helps.
Here the thread code:
class NFC_Thread : public QThread
{
Q_OBJECT
public:
NFC_Thread(NFC_Reader * Reader);
void run();
signals:
void NewTarget(nfc_target Target);
void TargetRemoved(nfc_target Target);
private:
int mError;
bool mStopPolling;
};
void NFC_Thread::run()
{
mError = 0;
mStopPolling = false;
while(!mStopPolling)
{
nfc_target Target;
mError = nfc_initiator_poll_target(mReader->GetDevice(), nmModulations, szModulations, mPollNr, mPollPeriod, &Target);
if(mError > 0)
{
cout << "NFC: found target" << endl;
}
#warning Bug in driver: Timeout generate a NFC_EIO Error, 'https://code.google.com/p/libnfc/issues/detail?id=224'
else if(mError > 0)
{
cout << "NFC: Error" << endl;
mStopPolling = true;
}
else
{
cout << "NFC: no target found" << endl;
}
}
}
MainWindow Code:
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
public slots:
void SetNewTarget(nfc_target Target);
void doTargetRemoved(nfc_target Target);
private:
bool event(QEvent *event);
void resizeEvent(QResizeEvent *);
void adjust();
Ui::MainWindow *ui;
QWebView * mWebView;
};
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
mWebView = new QWebView(this);
mWebView->load(QUrl("http://www.pbuchegger.at/"));
mWebView->show();
}
void MainWindow::SetNewTarget(nfc_target Target)
{
QString str = "NEW TARGET: \n";
{
char * s;
str_nfc_target(&s, Target, false);
str += s;
delete s;
}
//cout << "NFC: Target: " << str << endl;
mWebView->load(QUrl("http://www.google.at"));
update();
repaint();
mWebView->update();
qApp->processEvents();
/*QMessageBox msgBox;
msgBox.setText(str);
msgBox.exec();*/
}
void MainWindow::doTargetRemoved(nfc_target Target)
{
QString str = "TARGET REMOVED: \n";
{
char * s;
str_nfc_target(&s, Target, false);
str += s;
delete s;
}
//cout << "NFC: Target: " << str << endl;
mWebView->load(QUrl("http://www.cde.at"));
update();
repaint();
mWebView->update();
qApp->processEvents();
/*QMessageBox msgBox;
msgBox.setText(str);
msgBox.exec();*/
}
bool MainWindow::event(QEvent *event)
{
if(event->type() == QEvent::Resize)
{
adjust();
return true;
}
return false;
}
void MainWindow::resizeEvent(QResizeEvent *)
{
adjust();
}
void MainWindow::adjust()
{
mWebView->setGeometry(0, 0, ui->centralWidget->geometry().width(), ui->centralWidget->geometry().height());
}
main code:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
qRegisterMetaType<nfc_target>("nfc_target");
MainWindow w;
w.setWindowState(Qt::WindowMaximized);
NFC_Reader Reader;
nfc_device_string devs;
size_t nr;
QString str = "";
Reader.GetDevices(devs, nr);
if(nr > 0)
{
if(!Reader.InitReader(NULL))
{
str += "Error on init!";
}
else
{
Reader.Start_Polling();
str += "Started Polling!";
}
}
else
{
str += "No Device found!";
}
w.SetText(str);
SignalHelper Helper;
QObject::connect(Reader.GetThread(), SIGNAL(NewTarget(nfc_target)), &Helper, SLOT(doNewTarget(nfc_target)));
QObject::connect(Reader.GetThread(), SIGNAL(TargetRemoved(nfc_target)), &Helper, SLOT(doTargetRemoved(nfc_target)));
QObject::connect(&Helper, SIGNAL(NewTarget(nfc_target)), &w, SLOT(SetNewTarget(nfc_target)));
QObject::connect(&Helper, SIGNAL(TargetRemoved(nfc_target)), &w, SLOT(doTargetRemoved(nfc_target)));
w.show();
int ret = a.exec();
Reader.Abort_Polling();
return ret;
}
As u can see, I have a "Helper" class, this class is just getting the signal in a slot and starting again a signal which will be forward to the mainwindow. If i want to forward the signal directly to the mainwindow, nothing is happening (like the signal is not fired), but i was checking it with the Qt-About box, and the box is showing up.
Helper class:
class SignalHelper : public QObject
{
Q_OBJECT
public slots:
void doNewTarget(nfc_target Target);
void doTargetRemoved(nfc_target Target);
signals:
void NewTarget(nfc_target Target);
void TargetRemoved(nfc_target Target);
};
void SignalHelper::doNewTarget(nfc_target Target)
{
emit NewTarget(Target);
}
void SignalHelper::doTargetRemoved(nfc_target Target)
{
emit TargetRemoved(Target);
}
no compiler errors or linker errors. this code shows just the important stuff, all the unimportant stuff is removed. just for your information the project file:
QT += core gui testlib
QT += webkit
greaterThan(QT_MAJOR_VERSION, 4) {
QT += widgets
}
TARGET = NFC_GUI
TEMPLATE = app
SOURCES += main.cpp \
mainwindow.cpp \
nfc_thread.cpp \
nfc_reader.cpp \
signal_helper.cpp
HEADERS += mainwindow.h nfc_thread.h nfc_reader.h signal_helper.h
FORMS += mainwindow.ui
LIBS += -lnfc
Making my comment an answer:
Your function
bool MainWindow::event(QEvent *event)
{
if(event->type() == QEvent::Resize)
{
adjust();
return true;
}
return false;
}
eats any event which is handled in QMainWindow except for QEvent::Resize. You need to call the default behaviour for events you are not interested in:
bool MainWindow::event(QEvent *event)
{
if(event->type() == QEvent::Resize)
{
adjust();
return true;
}
// call the parent implementation
return QMainWindow::event(event);
}
Note you can also just simply implement QWidget::resizeEvent:
void MainWindow::resizeEvent(QResizeEvent *event)
{
adjust();
QMainWindow::resizeEvent(event);
}
If you're calling slots from signals between different threads, you need to make the connect calls with Qt::QueuedConnection as the Connection Type.