Thread never allowed access to synchronized block of code - java

The Future object is never able to obtain access to the synchronized block of code so it never finishes and never returns. There isn't anything accessing writeOut() besides the thread so I am not sure why it is block.
public class FileManager {
private void writeOut() throws BusinessException {
if(f.exists() && f.canWrite()) {
synchronized (this) {
try (FileWriter fileWriter = new FileWriter(f)) {
String endLine = "\n";
fileWriter.write("");
for (Entry entry : directory) {
fileWriter.append(entry.getLastName());
fileWriter.append(CSV_DELIMITER);
fileWriter.append(entry.getFirstName());
fileWriter.append(CSV_DELIMITER);
fileWriter.append(entry.getPhoneNumber());
fileWriter.append(CSV_DELIMITER);
fileWriter.append(entry.getAddress());
fileWriter.append(endLine);
}
} catch (IOException e) {
e.printStackTrace();
}
}
} else {
System.out.println(f.getAbsolutePath() + " doesn't exist or can't be written to");
}
}
public void addEntry(Entry entryModel, boolean notify) {
assert entryModel != null;
synchronized (this) {
AddEntryAction addAction = new AddEntryAction(entryModel, notify);
AddEntryActor actor = new AddEntryActor(addAction);
actor.execute();
deleteActor(actor);
}
}
Here is the method that is called by execute():
private void executeAsynchronously() {
Callable<String> asyncTask = () -> {
try {
ServiceFw.fileManager.writeBack();
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BusinessException e) {
notifyFailure();
}
return "write back operation";
};
future = executor.submit(asyncTask);
Runnable poll = () -> {
if(future!=null) {
notifySuccess();
} else {
notifyFailure();
}
};
poll.run();
}

Related

Replacing Future<Integer> with Future<Void>

I am writing an application that searches for Java files in a given directory and its subdirectories and writes all the strings from those files in reverse order to a new folder. Each directory and file is handled in a separate thread.
At the moment my program works correctly, but I want to change its behavior.
Right now, the program overwrites the files correctly and outputs the number of overwritten files to the console at the end. I want my program to just overwrite the files and display the line "All files overwritten" at the end. But I don't quite understand how I can change my code and replace Future (I think that's my problem). Here is part of the code from the Main class:
ExecutorService pool = Executors.newCachedThreadPool();
ReverseWritter reverseWritter = new ReverseWritter(dirToSearch, dirToStorePath + "//" + dirToStoreName, pool);
Future<Integer> res = pool.submit(reverseWritter);
try {
System.out.println(res.get() + " files reversed");
} catch (ExecutionException | InterruptedException e) {
e.printStackTrace();
}
pool.shutdown();
Here's the method that overwrites the file:
public boolean reverseWrite(File file) {
if (file.isFile() && file.toString().endsWith(".java")) {
String whereTo = dirToStorePathName + "\\" + file.getName().substring(0, file.getName().indexOf(".java")) + "Reversed" + ".java";
try ( Scanner myReader = new Scanner(file); FileWriter myWriter = new FileWriter(whereTo);) {
while (myReader.hasNextLine()) {
String data = myReader.nextLine();
myWriter.write(new StringBuffer(data).reverse().toString());
myWriter.write(System.getProperty("line.separator"));
}
} catch (FileNotFoundException e) {
System.out.println("An error occurred.");
e.printStackTrace();
return false;
} catch (IOException e) {
System.out.println("An error occurred.");
e.printStackTrace();
return false;
}
}
return true;
}
And this is the call method (my class implements the Callable interface):
#Override
public Integer call() {
int count = 0;
try {
File[] files = dirToSearch.listFiles();
ArrayList<Future<Integer>> result = new ArrayList<>();
for (File f : files) {
if (f.isDirectory()) {
ReverseWritter reverseWritter = new ReverseWritter(f, dirToStorePathName, pool);
Future<Integer> rez = pool.submit(reverseWritter);
result.add(rez);
} else if (reverseWrite(f)) {
count++;
}
for (Future<Integer> rez : result) {
count += rez.get();
}
}
} catch (ExecutionException | InterruptedException e) {
e.printStackTrace();
}
return count;
}
You just need to change the class to implement Callable<Void> and remove the operations which do the counting. Change the return type of call from Integer to Void.
public class ReverseWriterCallable implements Callable<Void> {
#Override
public Void call() throws Exception {
//do stuff
//don't do the counting operations
//when return type is Void you can only return null
return null;
}
}
Or implement Runnable and submit it to the executor service.
public class ReverseWriterRunnable implements Runnable {
#Override
public void run() {
//do stuff
//don't do the counting operations
}
}
Then just don't care about the result of the Future:
try {
res.get();
System.out.println("All files reversed");
} catch (ExecutionException | InterruptedException e) {
e.printStackTrace();
}
pool.shutdown();

Java try-with-resource implementation done by compiler

I was wondering, when exception occurs how try with resource statement manages to close resources before entering catch block.
When exception occurs execution immediately jumps to catch block. So where actually try-with-resource closes the resources.
To get better understanding of how it works I decided to see how compiler implements it. I wrote following code and and compiled it.
public class Test
{
public static void main(final String[] args) {
//I used same JDK for compilation and execution.
System.out.println("Java version: " + System.getProperty("java.version") + "\n");
try(CloseMe me = new CloseMe();
CloseMeToo meToo = new CloseMeToo()){
System.out.println("trying");
throw new Exception("try failed");
} catch(Exception e) {
System.out.println("failed");
System.out.println("\n");
System.out.println(e.getMessage());
System.out.println(e.getSuppressed()[0].getMessage());
System.out.println(e.getSuppressed()[1].getMessage());
}
}
}
class CloseMe implements AutoCloseable {
#Override
public void close() throws Exception {
System.out.println("me closing!");
throw new Exception("don't close me :o");
}
}
class CloseMeToo implements AutoCloseable {
#Override
public void close() throws Exception {
System.out.println("meToo closing!");
throw new Exception("don't close me too :O");
}
}
Output
Java version: 15.0.1
trying
meToo closing!
me closing!
failed
try failed
don't close me too :O
don't close me :o
Then I went to www.javadecompilers.com and tried the decompilers there. Two decompilers gave decent results: CFR 0.150 and Fernflower.
CFR is most readable and complete so posting it here.
public class Test
{
public static void main(final String[] args) throws Throwable{
System.out.println("Java version: " + System.getProperty("java.version") + "\n");
try {
Throwable throwable = null;
Object var2_4 = null; //<-- where this variable is used?
try {
CloseMe me = new CloseMe();
try {
CloseMeToo meToo = new CloseMeToo();
try {
System.out.println("trying");
throw new Exception("try failed");
}
catch (Throwable throwable2) {
throwable = throwable2; //<-- I put this line to make it work
if (meToo != null) {
meToo.close();
}
throw throwable2;
}
}
catch (Throwable throwable3) {
if (throwable == null) {
throwable = throwable3;
} else if (throwable != throwable3) {
throwable.addSuppressed(throwable3);
}
if (me != null) {
me.close();
}
throw throwable;
}
}
catch (Throwable throwable4) {
if (throwable == null) {
throwable = throwable4;
} else if (throwable != throwable4) {
throwable.addSuppressed(throwable4);
}
throw throwable;
}
}
catch (Exception e) {
System.out.println("failed");
System.out.println("\n");
System.out.println(e.getMessage());
System.out.println(e.getSuppressed()[0].getMessage());
System.out.println(e.getSuppressed()[1].getMessage());
}
}
}
I understand decompilers have limitations. Ideal decompiler would've given me same try-with-resource back and I wouldn't have seen these details. So it is ok.
My questions are:
In above decompiled code, variable var2_4 is unused. Also, I had to add a line to make it work like try-with-resource. I think the code is not complete. If there are any, can you add/explain missing parts?
If anyone, who understands bytecode, translate class file to exact java code would be great. Or give me pointers about where can I get the tools to do the job.
Thank you!
The behavior of try-with-resources is fully documented in the Java Language Specification, section 14.20.3. try-with-resources.
It specifically shows that the following abbreviated version of the question code:
try (CloseMe me = new CloseMe(); CloseMeToo meToo = new CloseMeToo()) {
System.out.println("trying");
} catch (Exception e) {
System.out.println("failed");
}
first gets converted to:
try {
try (CloseMe me = new CloseMe(); CloseMeToo meToo = new CloseMeToo()) {
System.out.println("trying");
}
} catch (Exception e) {
System.out.println("failed");
}
then to:
try {
final CloseMe me = new CloseMe();
Throwable #primaryExc1 = null;
try (CloseMeToo meToo = new CloseMeToo()) {
System.out.println("trying");
} catch (Throwable #t) {
#primaryExc1 = #t;
throw #t;
} finally {
if (me != null) {
if (#primaryExc1 != null) {
try {
me.close();
} catch (Throwable #suppressedExc) {
#primaryExc1.addSuppressed(#suppressedExc);
}
} else {
me.close();
}
}
}
} catch (Exception e) {
System.out.println("failed");
}
then to:
try {
final CloseMe me = new CloseMe();
Throwable #primaryExc1 = null;
try {
final CloseMeToo meToo = new CloseMeToo()
Throwable #primaryExc2 = null;
try {
System.out.println("trying");
catch (Throwable #t) {
#primaryExc2 = #t;
throw #t;
} finally {
if (meToo != null) {
if (#primaryExc2 != null) {
try {
meToo.close();
} catch (Throwable #suppressedExc) {
#primaryExc2.addSuppressed(#suppressedExc);
}
} else {
meToo.close();
}
}
}
} catch (Throwable #t) {
#primaryExc1 = #t;
throw #t;
} finally {
if (me != null) {
if (#primaryExc1 != null) {
try {
me.close();
} catch (Throwable #suppressedExc) {
#primaryExc1.addSuppressed(#suppressedExc);
}
} else {
me.close();
}
}
}
} catch (Exception e) {
System.out.println("failed");
}

java synchronized method seems not work

I have this code that is executed when a file is modified
public class WatchQueueReaderTask<Void> extends Task {
...
protected Object call() throws Exception {
try {
// get the first event before looping
WatchKey key = myWatcher.take();
while (key != null) {
// we have a polled event, now we traverse it and
// receive all the states from it
for (WatchEvent event : key.pollEvents()) {
WatchEvent.Kind eventType = event.kind();
if (eventType == OVERFLOW) {
continue;
}
process(event);
if (isCancelled()) {
System.out.println("WatchQueueReaderTask::call isCancelled");
return null;
}
}
key.reset();
key = myWatcher.take();
}
} catch (InterruptedException e) {
ArrayList<WatchFileItem> auxList = threadFileToWatch;
for (WatchFileItem obj : auxList) {
if (obj.file != null) {
try {
obj.file.close();
} catch (IOException ex) {
System.out.println("errore in file close");
Logger.getLogger(WatchQueueReaderTask.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
//e.printStackTrace();
}
System.out.println("Stopping thread");
return null;
}
...
private synchronized void process(WatchEvent evt) {
... }
}
I call it using:
ThreadFactory processingThreadFactoryForRealtime = null;
ExecutorService processingThreadFactoryForRealtimeExecutor = null;
WatchQueueReaderTask mywatchQueueReader = null;
processingThreadFactoryForRealtime = new ThreadFactory() {
#Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
t.setName("FileWatcherTask");
t.setDaemon(true);
return t;
}
};
processingThreadFactoryForRealtimeExecutor = Executors.newSingleThreadExecutor(processingThreadFactoryForRealtime);
mywatchQueueReader = new WatchQueueReaderTask(realtimePath, watcherServiceForRealtime, fileToWatchForRealtime);
processingThreadFactoryForRealtimeExecutor.execute(mywatchQueueReader);
The problem is that execute simultaneously multiple methods process() without waiting for the previous is completed.
Where am I wrong?

Java: EDT, SwingUtilities & GUILock

I am using an actionListener to trigger an sequence of events and ultimatley this code is called:
public class ScriptManager {
public static Class currentScript;
private Object ScriptInstance;
public int State = 0;
// 0 = Not Running
// 1 = Running
// 2 = Paused
private Thread thread = new Thread() {
public void run() {
try {
currentScript.getMethod("run").invoke(ScriptInstance);
} catch(Exception e) {
e.printStackTrace();
}
}
};
public void runScript() {
try {
ScriptInstance = currentScript.newInstance();
new Thread(thread).start();
State = 1;
MainFrame.onPause();
} catch (Exception e) {
e.printStackTrace();
}
}
public void pauseScript() {
try {
thread.wait();
System.out.println("paused");
State = 2;
MainFrame.onPause();
} catch (Exception e) {
e.printStackTrace();
}
}
public void resumeScript() {
try {
thread.notify();
System.out.println("resumed");
State = 1;
MainFrame.onResume();
} catch (Exception e) {
e.printStackTrace();
}
}
public void stopScript() {
try {
thread.interrupt();
thread.join();
System.out.println("stopped");
State = 0;
MainFrame.onStop();
} catch (Exception e) {
e.printStackTrace();
}
}
}
The runnable is created and ran, however, the problem occurs when I try to use the any of the other methods, they lock my UI. (I'm assuming this is because im running this on the EDT) Does anyone know how to fix this?
That's not how you use wait and notify. They need to be executed on the thread that you are trying to pause and resume. Which means you need to send a message to the other thread somehow. There are various ways to do this, but the other thread needs to be listening for this message, or at least check for it occassionally.

java semaphore idiom

I have a thread which does an action only when it gets exclusive access to 2 semaphores.
public void run(){
boolean a1=false;
boolean a2=false;
boolean a3=false;
while(true){
try{
if(res[1].tryAcquire()==true){
a1=true;
if((res[2].tryAcquire()==true){
a2=true;
if(res[3].tryAcquire()==true)){
a3=true;
System.out.println("Rolled the tobacco");
}
}
}
}
finally{
if(a1){
a1=false;
res[1].release();
}
if(a2){
a2=false;
res[2].release();
}
if(a3){
a3=false;
res[3].release();
}
}
}
}
}
Is there a better way to write this to make sure we do not upset the semaphore acquired count?
Is there a way to check if a semaphore is acquired by the current thread?
In Java 7 a try with Closeable is possible. There certainly must be nicer solutions.
public class Region implements Closeable {
private final Semaphore semaphore;
public Region(Semaphore semaphore) {
this.semaphore = semaphore;
if (!semaphore.tryAcquire()) {
throw NotAcquiredException(semaphore);
}
}
#Override
public void close() {
semaphore.release();
}
}
public class NotAcquiredException extends Exception { ... }
Usage:
public void run() {
boolean a1 = false;
boolean a2 = false;
boolean a3 = false;
while (true) {
try (Closeable r1 = new Region(res[1])) {
a1 = true;
try (Closeable r2 = new Region(res[2])) {
a2 = true;
try (Closeable r3 = new Region(res[3])) {
a3 = true;
System.out.println("Rolled the tobacco");
} catch (IOException e) {
}
} catch (IOException e) {
}
} catch (IOException e) {
}
}
You could separate each acquire into a try...finally, not shorter, but gets rid of some variables and makes it fairly obvious what should happen for each lock. (I changed the array to zero based)
public void run(){
while(true){
if(res[0].tryAcquire()){
try {
if(res[1].tryAcquire()) {
try {
if(res[2].tryAcquire()){
try {
System.out.println("Rolled the tobacco");
} finally {
res[3].release();
}
}
} finally {
res[2].release();
}
}
} finally{
res[1].release();
}
}
}
}
If you need to acquire a lot of locks or do this in several places, then maybe a helper class would be nice. At least hides the boilerplate code of acquire and releasing the semaphores.
public void run() {
SemaphoreHelper semaphoreHelper = new SemaphoreHelper(res);
while (true) {
try {
if (semaphoreHelper.aquireAll()) {
System.out.println("Rolled the tobacco");
}
} finally {
semaphoreHelper.releaseAquired();
}
}
}
private static class SemaphoreHelper {
private final Semaphore[] semaphores;
private int semaphoreIndex;
public SemaphoreHelper(Semaphore[] semaphores) {
this.semaphores = semaphores;
}
public void releaseAquired() {
while (semaphoreIndex > 0) {
semaphoreIndex--;
semaphores[semaphoreIndex].release();
}
}
public boolean aquireAll() {
while (semaphoreIndex < semaphores.length) {
if (!semaphores[semaphoreIndex].tryAcquire()) {
return false;
}
semaphoreIndex++;
}
return true;
}
}

Categories

Resources