I am trying to develop active object pattern in concurrent Java using java.util.concurrent classes.
I describe it using a Client and a Server. A sample Server is as:
class Server implements Runnable {
public final LinkedBlockingQueue que = new LinkedBlockingQueue();
private final ExecutorService es = Executors.newCachedThreadPool();
private Message currentMessage;
private boolean state = false;
public init() {
es.submit(this);
}
public void requestForServer() {
if (state) {
this.currentMessage.await();
}
state = true;
}
public void run() {
for(;;) {
Message m = que.take();
this.currentMessage = m;
this.es.submit(m);
}
}
}
And a sample Client:
class Client {
private Server server;
public Client(Server s) {
this.server = s;
}
public void doSomething() {
Message m = new Message(new Callable() {
public Object call() {
server.requestForServer();
}
});
this.server.que.add(m);
}
}
And a sample Message encapsulation is:
class Message<V> extends FutureTask<V> {
private Lock lock = new ReentrantLock();
private Condition condition = new Condition();
public Message(Callable<V> callable) {
super(callable);
}
public void run() {
try {
lock.lock();
super.run();
lock.unlock();
} catch(Exception e) {}
}
public void await() {
try {
condition.await();
} catch(Exception e) {}
}
public void signal() {
try {
condition.signalAll();
} catch(Exception e) {}
}
}
And a sample running code:
Server s = new Server();
Client c = new Client (s);
s.init();
c.doSomething();
I dropped some implementation details to get my message across.
Now, the problem is when in Server the state is true so the incoming message should wait and the await is called on the current message. However, I get IllegalMonitorStateException which means that the current message does not own the current thread to await on it. But, I believe this is strange since the current message gets called in the Server and its thread pool so the current message has also an access to the current thread of execution.
I'd be most thankful for any ideas or suggestions, or with a known working implementation of this pattern using java.util.concurrent. Thanks in advance.
UPDATE:
I discussed the solution I could deploy in this blog post. I hope it could help.
You have to actually acquire the lock when you await on its corresponding condition. Without that lock you cannot associate yourself to the condition directly. To demonstrate this:
public void await() {
lock.lock();
try {
condition.await();
} catch(Exception e) {}
finally{
lock.unlock();
}
}
That should resolve your IllegalMonitorStateException
On a side note of correctness you should always release a lock in a try{ } finally{ } manner, you can observe what I wrote as an example. The reason for this is if an exception occurs between lock().lock(); and super.run(); lock.unlock() will never be called.
Related
Faced the fact that when the database is unavailable, the queue grows because tasks stop running. What is the best way to set some timeout for tasks executed in method run()? May be there is some good approach with using ExecutorService?
#Service
public class AsyncWriter implements Writer, Runnable {
private LinkedBlockingQueue<Entry> queue = new LinkedBlockingQueue<>();
private volatile boolean terminate = false;
private AtomicInteger completedCounter = new AtomicInteger();
#PostConstruct
private void runAsyncWriter() {
Thread async = new Thread(this);
async.setName("Writer Thread");
async.setPriority(2);
async.start();
}
#Override
public void run() {
while (!terminate) {
try {
Entry entry = queue.take();
dao.save(entry);
completedCounter.incrementAndGet();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
#Override
public void write(Entry entry) {
queue.add(entry);
}
}
Maybe you can try RxJava
https://www.baeldung.com/rx-java
And you can set your aync funtions
Timeout in RxJava
I am new to using threads. In another class an instance of the ConnectionMaster class is created and started (extends thread). A Client object is given to the ConnectionMaster object which adds it to the list. The overridden run() method of the Thread class essentially listens for a client to be added to the list. Indeed it does listen and "hears" when a Client object is added to the list. However, although .hasNext() returns true .Next() causes an exception. What am I doing wrong?
The following methods are from class ConnectionMaster which extends Thread:
Constructor
public ConnectionMaster(){
clients = new Vector<>();
listIterator = clients.listIterator();
}
Public method for adding client objects to the list
#Override
public synchronized void addClient(Client client) {
listIterator.add(client);
}
This is the overridden thread method of the class Thread. It consistently checks for elements added to the list.
#Override
public void run(){
while(true){
while(listIterator.hasNext()){
processClient(listIterator.next()); //this is where error occurs
listIterator.remove();
}
while(listIterator.hasPrevious()){
processClient(listIterator.previous());
listIterator.remove();
}
}
}
////////////////////////////////UPDATE////////////////////////////////////
Thank You OldCurmudgeon and Stephen C.
Based on your feedback, my code has been modified thus:
Constructor
public ConnectionMaster(){
clients = new ArrayBlockingQueue<Client>(1024);
}
Method for receiving client objects
#Override
public synchronized void addClient(Client client) {
try {
clients.put(client);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Listener
#Override
public void run(){
while(true){
try {
processClient((Client)clients.take());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
This is a very strange way to implement Producer/Consumer. The usual way is to use a BlockingQueue.
public class TwoThreads {
public static void main(String args[]) throws InterruptedException {
System.out.println("TwoThreads:Test");
new TwoThreads().test();
}
// The end of the list.
private static final Integer End = -1;
static class Producer implements Runnable {
final BlockingQueue<Integer> queue;
public Producer(BlockingQueue<Integer> queue) {
this.queue = queue;
}
#Override
public void run() {
try {
for (int i = 0; i < 1000; i++) {
queue.add(i);
Thread.sleep(1);
}
// Finish the queue.
queue.add(End);
} catch (InterruptedException ex) {
// Just exit.
}
}
}
static class Consumer implements Runnable {
final BlockingQueue<Integer> queue;
public Consumer(BlockingQueue<Integer> queue) {
this.queue = queue;
}
#Override
public void run() {
boolean ended = false;
while (!ended) {
try {
Integer i = queue.take();
ended = i == End;
System.out.println(i);
} catch (InterruptedException ex) {
ended = true;
}
}
}
}
public void test() throws InterruptedException {
BlockingQueue<Integer> queue = new LinkedBlockingQueue<>();
Thread pt = new Thread(new Producer(queue));
Thread ct = new Thread(new Consumer(queue));
// Start it all going.
pt.start();
ct.start();
// Wait for it to finish.
pt.join();
ct.join();
}
}
What am I doing wrong?
Quite a lot actually.
First thing you are doing wrong is (apparently) using an ListIterator object in multiple threads. The ListIterator and Iterator implementations for Vector are not thread-safe1, so what you are doing is potentially hazardous.
The second thing is that even if the iterators / list iterators were thread-safe, you are performing a sequence of operations (e.g. hasNext, next, remove) without doing anything to ensure that the sequence of operations is performed in a way that is threadsafe. There is a distinct possibility that two threads could be performing the same sequence simultaneously on the shared iterator, and that one could interfere with the other.
I'm not sure what to suggest in order to fix your code. Two threads sharing an iterator is not going to work.
It would probably be better to ditch it, and use some kind of Queue as suggested by #OldCurmugeon.
Either problem 1 or problem 2 (as outlined above) could give rise to NoSuchElement exceptions.
1 - This is apparent from examining the source code - http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8u40-b25/java/util/Vector.java#Vector.ListItr .
I must design a simple server which receives messages from multiple nodes and stores them in a message repository.
The code for the server is :
public class CommunicationServer implements Runnable {
private List<String> messages;
private MessageRepository messageRepository;
private boolean serverBusy;
public CommunicationServer() {
messages = new ArrayList<String>();
messageRepository = new MessageRepository();
serverBusy = false;
}
#Override
public void run() {
try {
while (!Thread.interrupted()) {
synchronized (this) {
if (messages.size() > 10) {
serverBusy = true;
addMessageToRepository();
notifyAll();
}
else {
serverBusy = false;
wait();
}
}
}
}
catch (InterruptedException e) {
System.out.println(e.getMessage());
}
}
public synchronized void receiveMessage(String message) {
if (messages.size() < 10) {
messages.add(message);
}
}
private void addMessageToRepository() {
if (messages.size() != 0) {
messageRepository.addMessage(messages.remove(0));
}
}
public void showMessageRepository() {
messageRepository.showStoredMessages();
}
public synchronized boolean isServerBusy() {
return serverBusy;
}
}
The code for the node is:
public class Node implements Runnable {
private static final String CHARACTERS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZ0123456789";
private static final int MESSAGE_LENGHT = 5;
private Random random = new Random();
private CommunicationServer communicationServer;
public Node(CommunicationServer communicationServer) {
this.communicationServer = communicationServer;
}
#Override
public void run() {
try {
while (!Thread.interrupted()) {
while (communicationServer.isServerBusy()) {
wait();
}
communicationServer.receiveMessage(generateRandomString());
}
}
catch (InterruptedException e) {
System.out.println(e.getMessage());
}
}
private String generateRandomString() {
StringBuffer randomMessage = new StringBuffer();
for (int i = 0; i < MESSAGE_LENGHT; i++) {
randomMessage.append(CHARACTERS.charAt(random.nextInt(51)));
}
return randomMessage.toString();
}
}
In main I just create a thread for the server and 5 threads for the nodes and let them run for some time. The server sleeps until it receives 10 messages, after that it must wake up to process the messages. The problem is I can't figure it out where to call notifyAll() in order to wake the thread responsible for the server.
Making CommunicationServer implements Runnable doesn't really make sense and exposes your basic misunderstanding: you identify the actors in your process (server, client) with threads. A thread is not the actor; a thread is where actor's code gets executed.
So, when in your CommunicationServer you say wait(), you don't make the server wait for messages; you make that particular thread wait on the server object as its monitor. Likewise, then you say notifyAll(), you are not "notifying all servers"; you are notifying all threads waiting on that particular monitor. It should be some code in the client which notifies the threads that are currently waiting on the server's monitor, and some code in the server which notifies those waiting on the client monitor.
As a general rule of thumb, when you find yourself using both wait() and notify() within the same synchronized block, you can be pretty sure there's something wrong with your logic.
This is the first time I've ever created a multi-threaded application in Java that that will run continuously until canceled and I'm having trouble shutting down/interrupting my threads.
I have some threads that communicate with a Mediator which encapsulates a TransferQueue, an ExecutorService, and facilitates communication between producing and consuming threads.
I'm using this Mediator instead of Future because TransferQueue is a lot more block-friendly when it comes to a single consumer handling multiple producers (producer threads can mediator.put(E e) any time they want, and consumer threads can just wait on E e = mediator.take() for something to be available) and I do not want to waste CPU cycles polling.
The design is very clean, fast, and effective, but I'm having trouble interrupting blocking on queue.take(), serverSocket.accept(), and interrupting the threads as a whole.
The producers:
public class SocketProducer implements Colleague<Socket> {
private Mediator<Socket> mediator;
private ServerSocket serverSocket;
private Integer listeningPort;
private volatile boolean runnable = true;
public SocketProducer(Mediator<Socket> mediator) {
this.mediator = mediator;
}
public Colleague<Socket> setListeningPort(Integer listeningPort) {
this.listeningPort = listeningPort;
return this;
}
public Void call() throws Exception {
serverSocket = new ServerSocket(listeningPort, 10);
while (runnable) {
Socket socket = serverSocket.accept(); // blocks until connection
mediator.putIntoQueue(socket);
}
return null;
}
public void interrupt() {
// ?
runnable = false;
serverSocket.close();
// ?
}
}
and the consumer:
private class SocketConsumer implements Colleague<Socket> {
private Mediator<Socket> mediator;
private volatile boolean runnable = true;
public SomeConsumer(Mediator<Socket> mediator) {
this.mediator = mediator;
}
public Void call() throws Exception {
while (runnable) {
Socket socket = mediator.takeFromQueue(); // blocks until element is in queue
}
return null;
}
public void interrupt() {
// ?
runnable = false;
// ?
}
}
The Colleague interface just extends Callable, to give some additional capability to the Mediator in managing its producer/consumer colleagues (ie: calling for:each colleague.interrupt()).
I've tried a lot of methods, throwing InterruptedException in various places, catching InterruptedException in various places, letting threads return an instance of their Thread to the mediator for interruption. Everything I've tried has been so ineffective that it feels like I'm missing some crucial piece to this puzzle.
So far the most effective method I've seen is the poison pill (which would be great if the queues didn't throw NPE on a null insertion), and all the methods I've tried of introducing a poison generic have failed because of ClassCastException (trying to cast Object to Socket, trying to instantiate a generic Socket, etc.).
I'm really not sure where to go from here. I'd really like to be able to cleanly terminate these threads on demand.
Completed solutions:
public class SocketProducer implements Colleague<Socket> {
private static final Logger logger = LogManager.getLogger(SocketProducer.class.getName());
private Mediator<Socket> mediator;
private ServerSocket serverSocket;
private Integer listeningPort;
private volatile boolean runnable = true;
public SocketProducer(Mediator<Socket> mediator) {
this.mediator = mediator;
}
public Colleague<Socket> setListeningPort(Integer listeningPort) {
this.listeningPort = listeningPort;
return this;
}
public Void call() throws Exception {
serverSocket = new ServerSocket(listeningPort, 10);
logger.info("Listening on port " + listeningPort);
while (runnable) {
try {
Socket socket = serverSocket.accept();
logger.info("Connected on port " + socket.getLocalPort());
mediator.putIntoQueue(socket);
} catch (SocketException e) {
logger.info("Stopped listening on port " + listeningPort);
}
}
return null;
}
public void interrupt() {
try {
runnable = false;
serverSocket.close();
} catch (IOException e) {
logger.error(e);
}
}
}
public class SocketConsumer implements Colleague<Socket> {
private static final Logger logger = getLogger(SocketConsumer.class.getName());
private Mediator<Socket> socketMediator;
public SocketConsumer(Mediator<Socket> mediator) {
this.socketMediator = mediator;
}
public Void call() throws Exception {
while (!Thread.currentThread().isInterrupted()) {
try {
Socket socket = socketMediator.takeFromQueue();
logger.info("Received socket on port: " + socket.getLocalPort());
} catch (InterruptedException e) {
logger.info("Interrupted.");
Thread.currentThread().interrupt();
}
}
return null;
}
public void interrupt() {
Thread.currentThread().interrupt();
}
}
I think poison pills will only make things more complicated, so I'd keep it simple.
As for the ServerSocket, this answer suggests that calling close() should be enough to interrupt it.
As for BlockingQueue, consumer can look like this:
// you can use volatile flag instead if you like
while (!Thread.currentThread.isInterrupted()) {
try {
Object item = queue.take();
// do something with item
} catch (InterruptedException e) {
log.error("Consumer interrupted", e);
Thread.currentThread().interrupt(); // restore flag
}
}
Then in your Mediator you can just call interrupt() on a consumer thread.
A poison pill is straight forward.
private static Socket poisonPill = new Socket();
public Void call() throws Exception {
while (runnable) {
Socket socket = mediator.takeFromQueue(); // blocks until element is in queue
if (socket == poisonPill) {
// quit the thread...
}
}
return null;
}
Note the socket == poisonPill. This is an equality check that they're the exact same instance, so that's how the poisonPill works yet still being type safe.
Hi I was trying to understand wait notify and i see this behaviour in the code that 2 threads are printing statements inside synchronized block on same object.
public class WaitNotifyExample {
/**
* #param args
*/
public static void main(String[] args) {
Message msg = new Message("process it");
Waiter waiter = new Waiter(msg);
new Thread(waiter,"waiter").start();
Waiter waiter1 = new Waiter(msg);
new Thread(waiter1, "waiter1").start();
Notifier notifier = new Notifier(msg);
new Thread(notifier, "notifier").start();
//System.out.println("All the threads are started");
}
}
class Message {
private String msg;
public Message(String str){
this.msg=str;
}
public String getMsg() {
return msg;
}
public void setMsg(String str) {
this.msg=str;
}
}
class Waiter implements Runnable{
private Message msg;
public Waiter(Message m){
this.msg=m;
}
#Override
public void run() {
String name = Thread.currentThread().getName();
synchronized (msg) {
try{
System.out.println(name+" waiting to get notified at time:"+System.currentTimeMillis());
msg.wait();
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println(name+" waiter thread got notified at time:"+System.currentTimeMillis());
//process the message now
System.out.println(name+" processed: "+msg.getMsg());
}
}
}
class Notifier implements Runnable {
private Message msg;
public Notifier(Message msg) {
this.msg = msg;
}
#Override
public void run() {
String name = Thread.currentThread().getName();
System.out.println(name+" started");
try {
Thread.sleep(1000);
synchronized (msg) {
msg.setMsg(name+" Notifier work done");
//msg.notify();
msg.notifyAll();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Here is the output of the program:
-waiter waiting to get notified at time:1393849891481
-notifier started
-waiter1 waiting to get notified at time:1393849891483
-waiter1 waiter thread got notified at time:1393849892483
-waiter1 processed: notifier Notifier work done
-waiter waiter thread got notified at time:1393849892483
waiter processed: notifier Notifier work done
Read the Javadoc on Object.wait:
The thread releases ownership of this monitor and waits until another thread notifies threads waiting on this object's monitor
While a thread is blocked inside msg.wait, it does not own msg's monitor. Any other thread is free to acquire it.
The code is working as intended: no single thread is interfering with the output of your messages, as otherwise (if the stream wasn't synchronized internally) those letters and words would be completely mixed up and print gibberish.
However once you call wait, you put the current thread on hold and release the lock on the monitor, so other threads can print something in the meantime.
And another thing your code demonstrates very well: as timing with threads is undefined, it can happen that at the time notifyAll() is called, one, many or zero threads are actually waiting. Which is one of the common wait/notify issues, if Thread B already called notify before Thread A is even waiting.
In addition please note that synchronized/wait/notify is a very basic "brute force" method of thread synchronization that comes with many pitfalls and isn't very fast either as many threads are usually put on hold. It can be used for basic and simple code, but if you really want to dive into threading, you should not use it, but use the concurrent package and it's classes and features instead. The same code could for example be written using a LinkedBlockingQueue<String> instead of using synchronized.
Ok. I think important point already covered that is wait() release the monitor/lock so other thread can come to synchronized block. But I wanted to add 2 important point.
1. when use wait() don't forget to check for condition when or on which you should wait. You might become victim of spurious wakeup calls. Check this link
http://handling-thread.blogspot.co.uk/2012/11/what-is-spurious-wakeup-while-wait-in.html
2. If you are considering wait-notify approach I would suggest go for latest solution for the same approach which is using Condition.await-signal
For your reference I have updated the code by Condition approach.
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class WaitNotifyExample {
/**
* #param args
*/
public static void main(String[] args) {
Message msg = new Message("process it");
Waiter waiter = new Waiter(msg);
new Thread(waiter, "waiter").start();
Waiter waiter1 = new Waiter(msg);
new Thread(waiter1, "waiter1").start();
Notifier notifier = new Notifier(msg);
new Thread(notifier, "notifier").start();
//System.out.println("All the threads are started");
}
}
class Message {
final Lock lock = new ReentrantLock();
final Condition msgAvailable = lock.newCondition();
private String msg = null;
public Message(String str) {
this.msg = str;
}
public String getMsg() {
return msg;
}
public void setMsg(String str) {
this.msg = str;
}
public void lock() {
lock.lock();
}
public void await() throws InterruptedException {
msgAvailable.await();
}
public void unlock() {
lock.unlock();
}
public void signal() {
msgAvailable.signal();
}
public void signalAll() {
msgAvailable.signalAll();
}
}
class Waiter implements Runnable {
private Message msg;
public Waiter(Message m) {
this.msg = m;
}
#Override
public void run() {
String name = Thread.currentThread().getName();
msg.lock();
try {
System.out.println(name + " waiting to get notified at time:" + System.currentTimeMillis() + " Object: " + msg);
//You missed while condition which is very important aspect of wait-notify. You can check this link
//http://handling-thread.blogspot.co.uk/2012/11/what-is-spurious-wakeup-while-wait-in.html
while(msg.getMsg() == null)
msg.await();
//msg.wait();
System.out.println(name + " waiter thread got notified at time:" + System.currentTimeMillis() + " Object: " + msg);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
msg.unlock();
}
//process the message now
System.out.println(name + " processed: " + msg.getMsg());
}
}
class Notifier implements Runnable {
private Message msg;
public Notifier(Message msg) {
this.msg = msg;
}
#Override
public void run() {
String name = Thread.currentThread().getName();
System.out.println(name + " started");
msg.lock();
try {
Thread.sleep(1000);
msg.setMsg(name + " Notifier work done");
//msg.notify();
msg.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
msg.unlock();
}
}
}