There are two threads. One is manipulating x and the other is displaying x. How can I use synchronized, interrupt, wait and notify to have mutual exclusion. The image shows this.
Execution image
I have came up with this solution but iam not sure if its correct.
Write
synchronized(x){
x = x + 1;
notify();
try{
wait();
}
catch(InterruptedException e){
}
}
Read
synchronized(x){
try{
wait();
}
catch(InterruptedException e){
}
System.out.print(x);
}
You've already used synchronized(x) {} closure to make sure this is not going to happen. What you are doing is correct. If your statements are in a separate method, you can also make your method synchronized so that it will not get affected until it gets out of this method.
public synchronized void doSmth() {
//do smth;
}
Related
I have method in class MyClassB which is triggered asynchronously from a method of MyClassA:
public void getProductCall()
{
new Thread(new Runnable() {
#Override
public void run() {
try {
productRequest = service.createS4ProductRequest(getRepriceItems());
//Below is a rest call to another system
String response = pricing.getS4ProductResponse(quote.getAssetQuoteNrAndVrsn(), productRequest);
//I'm using the below 2 lines to check from ClassA's method to see if this process has ended
setProductResponse(response);
productPriceProcessEnded=true;
} catch (Exception e) {
productPriceErrorOccured=true;
e.printStackTrace();
}
}
}).start();
}
This is the piece of code in MyClassA i used to check if the above method is complete.
for(int i=0;i<1000000000;i++)
{
if(!networkAsynCalls.isListPriceErrorOccured())
{
if(networkAsynCalls.isListPriceprocessEnded())
{
return networkAsynCalls.getListReponse();
}
else
{
Thread.sleep(250);
continue;
}
}
else
return null;
}
instead of using this random for loop can i use some inbuilt method or service pool or something ?
Because,
1) This thread on method is in another class
2) In class MyClassB i have few more methods like this, so i need to check the status of all the methods in MyClassA
Thanks for any help.
If I undestand what you're trying to do is dispatch some code to be ran asynchronously, then be able to wait until it is completed (successfully or failed). If that's the case, you should take a look at Futures.
Here is an example based on the Javadoc:
FutureTask<String> future =
new FutureTask<String>(new Callable<String>() {
public String call() {
// do stuff
return "result";
}});
This code creates an object "future" that can be invoked to execute searcher.search(target). At this point, the code is not executed at all. You simply have an object representing a computation that may be executed asynchronously. To do so, you'd call:
ExecutorService executor = Executors.newFixedThreadPool(5);
executor.execute(future);
This snippet created an Executor (which is a fixed pool of 5 threads), then handed over the future to it for execution. The executor will run the computation from Future asynchronously.
Future offers some methods (see the Javadoc) to wait until completion, cancel, check completion status, etc. For example,
String result = future.get();
will block, waiting for the result indefinitely. A get(10, TimeUnit.SECONDS) will wait for 10 seconds and if the future has not completed, throw.
Context:
As I understand, BlockingQueue is used to pass data between threads aka producer-consumer problem.
For example, in my case I use it to store received DatagramPackets so that other thread can process them. For now it just logs all incoming packets to a log file.
Here is the code I used to imitate the process:
Cons c = new Cons();
new Thread(c).start();
int i = 0;
byte[] databuf = new byte[1024];
DatagramPacket packet = new DatagramPacket(databuf, databuf.length);
try (DatagramSocket socket = new DatagramSocket(5555)){
while (10 < System.currentTimeMillis()) {
socket.receive(packet);
c.add(packet);
socket.send(new DatagramPacket("OK".getBytes(), "OK".getBytes().length, packet.getAddress(),
packet.getPort()));
}
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
Cons class handles writing to BlockingQueue and logging it in separate threads :
private static class Cons implements Runnable {
LinkedBlockingQueue<DatagramPacket> q = new LinkedBlockingQueue<>();
#Override
public void run() {
while (10 < System.currentTimeMillis()) {
try {
DatagramPacket packet = q.take();
logger.log(Level.INFO, "!" +"Message:" + new String(packet.getData(), packet.getOffset(),
packet.getLength()));
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void add(DatagramPacket p) throws InterruptedException {
q.put(p);
}
Client side just sends set number of packets that this server receives.
Problem:
If thread that does reading from queue is somehow delayed, it starts to skip elements. In code example above it's imitated with Thread.sleep() but even logging alone is enough to make it skip few elements occasionally. And longer it takes for thread to request next element in queue more elements it skips. Using drainTo() provides same result.
In short, it rather behaives like single-element variable and not as queue. I don't understand why doesn't it just store all elements added so that handling thread can take them one-by-one and read?
Question:
Am I doing something wrong or is such behaviour intended?
Although now that I think about it, if even logging alone makes it so handler can't keep up with queue growing, how do I implement processing packets from multiple users? Do I have to create a different thread for each packet? That doesn't quite seems rational.
Please help me write Junit for this piece of code using Mockito /Powermock, Finding it difficult due to lamda expression and executor service.
public class myClass {
ExecutorService executorService;
public void testMethod(String a){
Thread thread = new Thread(() -> {
//logic
a= testDAo.getStatus();
while (true) {
if (Thread.interrupted()) {
break;
}
if (a() != "done" || a() != "fail") {
Thread.yield();
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
}
} else {
break;
}
}
}
Future task = executorService.submit(thread);
while (!task.isDone()) {
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
}
}
}
}
Various things here:
first of all: for testing executors and parallel execution, using a same thread executor can be extremely helpful (because it takes out the parallel aspect)
you have difficulties writing a unit test - because your production code is way too complicated.
Thus the real answer is: step back and improve your production code. Why again are you pushing a thread into an executor service?
The executor service is already doing things on a thread pool (at least that is how you normally use them). So you push a thread into a thread pool, and then you have code that waits "two" times (first within that thread, and then outside on the future). That just adds a ton of complexity for small gain.
Long story short:
I would get rid of that "inner thread" - just have the executor task wait until the result becomes available
Then: if lambda's give you trouble - then don't use them. Just create a named small class that implements that code. And then you can write unit tests for that small class. In other words: don't create huge "units" that do 5 different things. The essence of a good unit is to one thing (single responsibility principle!). And as soon as you follow that idea testing becomes much easier, too.
I'm trying to do some optimization in my code and would like to spawn a thread where I do a time consuming operation. During the implementation of that optimization I was running into an issue which was driving me crazy. I simplified the issue and created a test case for that specific issue: (I'm using SpringJUnit4ClassRunner so the transaction is properly started at the beginning of the testCRUD method)
Could someone help me understand why the foundParent is null in the thread ?
private Semaphore sema = new Semaphore(0, false);
private long parentId;
#Test
public void testCRUD() {
//create
DBParent parent = null;
{
parent = new DBParent();
parentDao.persist(parent);
parentId = parent.getId();
assertTrue(parentId > 0);
parentDao.flush();
}
(new Thread(
new Runnable() {
public void run()
{
System.out.println("Start adding childs !");
DBParent foundParent = parentDao.findById(parentId);
assertTrue(foundParent != null); //ASSERTION FAILS HERE !!!!
System.out.println("Releasing semaphore !");
sema.release();
System.out.println("End adding childs !");
}
})).start();
try {
System.out.println("Acquiring semaphore !");
sema.acquire();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
=============================EDITED===================================
As per one comment suggestion, I created a threadManager bean which spawn the thread. Here is the code of the threadManager:
public class ThreadManager {
#Transactional(propagation=Propagation.REQUIRES_NEW)
public void executeTask(String Name, Runnable task) {
(new Thread(task, Name)).start();
}
}
Then in the previous test, instead of staring the thread manually, I just post it in the thread manager like this:
#Autowired private ParentDao parentDao;
#Autowired private ThreadManager threadManager;
private Semaphore sema = new Semaphore(0, false);
private long parentId;
#Test
public void testCRUD() {
//create
DBParent parent = null;
{
parent = new DBParent();
parentDao.persist(parent);
parentId = parent.getId();
assertTrue(parentId > 0);
parentDao.flush();
}
threadManager.executeTask("BG processing...",
new Runnable() {
public void run()
{
System.out.println("Start adding childs !");
DBParent foundParent = parentDao.findById(parentId);
assertTrue(foundParent != null); //ASSERTION FAILS HERE !!!!
System.out.println("Releasing semaphore !");
sema.release();
System.out.println("End adding childs !");
}
});
try {
System.out.println("Acquiring semaphore !");
sema.acquire();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
Unfortunately this doesn't work either !!! :-(
The transaction context is bound to the thread. So the code in the spawned thread doesn't run in the same transaction context as the code in the initial thread. So, due to transaction isolation (the I in ACID), the spawned thread doesn't see what the initial thread's transaction is inserting in the database.
You can bind Spring transaction to a new thread, to run transactions & Hibernate/JPA access in it. But this has to be a different TX and JPA/HB session from other threads.
Spring code for OpenSessionInViewFilter, is a reasonable an example of how to bind Hibernate session to Spring's TX management. You can strip this down to fairly minimal code.
See:
org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
OpenSessionInViewFilter.doFilterInternal() -- this is where it actually binds it
TransactionSynchronizationManager.bindResource()
TransactionSynchronizationManager.unbindResource()
TransactionSynchronizationManager.getResource()
In one project (IIRC) I wrapped this functionality into a 'ServerThreadHb' class, to setup & save previous thread-bindings on construction -- with a restore() method to be called in a finally block, to restore previous bindings.
For your posted code sample, there isn't much point in running work on a separate thread -- since you synchronously wait for the work to be done. However I assume you were planning to remove that constraint & extend that functionality.
I am developing a Java-ME Based Mobile Application. Now My Requirements are like whenever I am updating one of my RMS, I want my application to be stay in a Freeze kind of mode; which means no other action like clicking button or anything else should happen. My Method is already "Synchronized".
Kindly guide me regarding this question.
Thanks.
The best way to handle this is to "serialize" your tasks. You can do this with a message queue - a class that maintains a Vector of message objects (tasks) and runs code based on each message. The queue runs on a thread that processes each task (message) in series. You create a simple message class for the different tasks - read RMS etc. A message can be an Integer if you like that wraps a number. The operation of adding and retrieving messages is synchronized but the code than does the tasks is not and runs on a simple switch block. The benefit of serializing your tasks is you don't have to worry about concurrency. Here is some of the essential code from a class I use to do this.
class MessageQueue implements Runnable{
Vector messages;
Thread myThread;
volatile boolean stop;
public void start() {
stop=false;
myThread=new Thread(this);
myThread.start();
}
// add message to queue - this is public
public synchronized void addMessage(Message m) {
messages.addElement(m);
if(stop) {
start();
} else {
// wake the thread
notify();
}
}
// get next message from queue - used by this thread
private synchronized Message nextMessage() {
if(stop) return null;
if(messages.isEmpty()) {
return null;
} else {
Message m=(Message)messages.firstElement();
messages.removeElementAt(0);
return m;
}
}
public void run() {
while (!stop) {
// make thread wait for messages
if (messages.size() == 0) {
synchronized (this) {
try {
wait();
} catch (Exception e) {
}
}
}
if (stop) {
// catch a call to quit
return;
}
processMessage();
}
}
}
// all the tasks are in here
private void processMessage() {
Message m = nextMessage();
switch (m.getType()) {
case Message.TASK1:
// do stuff
break;
case Message.TASK2:
// do other stuff
break;
case Message.TASK3:
// do other other stuff
break;
default: //handle bad message
}
}
}
What you are asking is very code depended. Usually when you want to make some synchronic actions you just write them one after the other. in java it's more complected, since sometimes you "ask" the system to do something (like repaint() method). But since the RMS read/write operations are very quick (few millisecond) i don't see any need in freesing.
Could you please provide some more information about the need (time for RMS to respond)? does your code runs on system thread (main thread) or your own thread?
I want my application to be stay in a Freeze kind of mode; which means no other action like clicking button or anything else should happen.
First of all I would strongly advise against real freezing of UI - this could make a suicidal user experience for your application.
If you ever happened to sit in front of computer frozen because of some programming bug, you may understand why approach like this is strongly discouraged. As they describe it in MIDP threading tutorial, "user interface freezes, the device appears to be dead, and the user becomes frustrated..."
This tutorial by the way also suggests possibly the simplest solution for problems like you describe: displaying a wait screen. If you don't really have reasons to avoid this solution, just do as tutorial suggests.
To be on a safe side, consider serializing tasks as suggested in another answer. This will ensure that when RMS update starts, there are no other tasks pending.