Java. I have two threads. one will be continuously monitoring for some events and based on the events, it will be updating (addition or deletion) a file. the other thread which is a timer task event, will be updating the same file in regular intervals of time. I want the threads to update the file when the other thread is not accessing the file. I couldn't use locks as file updating code part is independent for each thread and in different java classes. how can i do so? thanks in advance.
You can use synchronization.
public synchronized void update() {
..
..
..
}
so only one thread access the method. Other will wait on the lock.
If you have add,update,delete method
then,
private static Object LOCK = new Object();
public void update() {
synchronized(LOCK) {
..
..
..
}
}
public void add() {
synchronized(LOCK) {
..
..
..
}
}
public void delete() {
synchronized(LOCK) {
..
..
..
}
}
So Only one thread can able to edit/delete/add the file.
if one thread is adding , second thread is trying to delete then it will wait first thread to add.
synchronized void updateFILE
{
//Your operation here
}
So at a time one thread can perform opetation.. You can have look at here
Perhaps you could:
Create a wrapper class around your unsafe file-updater-class.
Make that wrapper class thread-safe by adding your synchronization or locks that clearly defines the critical sections and handle all exceptions appropriately (for example, unlock the critical section in a finally-block)
Let the other threads call your wrapper class instead.
Related
Is there a way to communicate between thread such as get variables with getters as they are being updated in a different thread
For example if im loading images in a runnable thread like so:
Thread t1 = new Thread(new Runnable(){
public void run(){
//Ido the loading here
}
}
is there a way i can communicate to that like get a value of a var for example:
Thread t1 = new Thread(new Runnable(){
public void run(){
//Ido the loading here
name = "dsad";
}
public void getName(){ return name }
}
but it dosnt seen to work
As for thread communicating, there's java.util.concurrent.Exchanger.
In your particular case, it also possible to use CompletableFuture from Java 8, since Exchanger allows multiple communications (both of threads continue executing), which is possibly not your case.
Manually creating threads may cause different issues:
creating thread each time is expensive operation,
creating lots of threads which run at the same time involves possible scheduler problems, memory issues (each thread has it's own stack, ...),
publishing values not in safe way (see Safe Publication and Safe Initialization topics) may cause data races, which are really bad
So, combination of java.util.concurrent.ExecutorService and java.util.concurrent.CompletableFuture may allow you thread-safe and easy readable way to perform asynchronous loading.
You need to create a new public type. Using an anonymous class means no other class can see its methods, as there's no type besides Runnable that they can see.
public class MyTask implements Runnable(){
private volatile String name;
public void run(){
//I do the loading here
name = "dsad";
}
public void getName(){ return name }
}
In my project I am facing weird issue with thread.
This issue is only occurring when I am running multiple thread at
once(load testing).
In my project there are multiple Interceptors which intercepts request/response at different level in application and send the request/response to WritetoFile class which writes the details into a flat file using log4j framework.
Below is the sample interceptor code. There are multiple interceptor and each can process in parallel.
/*we have multiple Interceptor class which will pre-process the
request/response and then send it to WritetoFile*/
public class IntercerptorA {
// some code ...
public synchronized void sendRequestToWritetoFile(IRequest request,IResponse response){
WritetoFile wtf = new WritetoFile(); //this class is responsible for writing request/response information into LOG file
wtf.setRequest(request);
wtf.setResponse(response);
Thread thread=new Thread(wtf, "t1");//**assume wtf.getRequest is having "ABC"**
thread.start();
}
}
Now suppose there 2 more Interceptor and has only single line difference in the code.
//For interceptorB
Thread thread=new Thread(wtf, "t2");//**assume wtf.getRequest is having "DEF"**
//For interceptorC
Thread thread=new Thread(wtf, "t3");//**assume wtf.getRequest is having "XYZ"**
Below is the code for WritetoFile class -:
public class WritetoFile implements Runnable{
private volatile IRequest request;
private volatile IResponse response;
public synchronized IRequest getRequest() {
return request;
}
public synchronized void setRequest(IRequest request) {
this.request = request;
}
public synchronized IResponse getResponse() {
return response;
}
public synchronized void setResponse(IResponse response) {
this.response = response;
}
#Override
public void run() {
// I have added synchronized as I was trying to resolve the issue
synchronized(WritetoFile.class){
putItInFile(this.request,this.response);
}
}
private synchronized void putItInFile (IRequest request,IResponse response){
// This is the logger where I find discrepancies
LOGGER.info("Current thread is : "+Thread.currentThread().getName()+" data is"+request);
//some code and method call
}
}
Having said that, now when I am running a single request the LOGGER.info("Current thread is : "+Thread.currentThread().getName()+" data is"+request); line is giving output as below -:
Current thread is t1 data is ABC
Current thread is t2 data is DEF
Current thread is t3 data is XYZ
which is perfectly fine. BUT on running multiple thread at once I am getting sometime wrong output as below -:
Current thread is t1 data is DEF
Current thread is t2 data is DEF
Current thread is t3 data is XYZ
It seems to be that before thread t1 can use the value of "wtf" object in method putItInFile , thread t2 have already reset the wtf value using setter in interceptorB. But what my thinking is, when I am creating new instance WritetoFile class for each thread ,how is thread t2 operation changing thread t1 cache. Please let me know where am I going wrong and what I need to change.
Thanks in advance :)
Using synchronized everywhere does not make a class thread safe.
In your case, as soon as WritetoFile.setRequest(request1) returns there is a window where the lock is not held and any other thread is free to call it before there is an opportunity for it to be used.
Rather than assigning the requests to an instance variable you would be better off adding them to one of the java.util.concurrent queue classes and consuming them from the queue in the Thread.run() method.
Have a look at the java.util.concurrent javadoc as there are heaps of examples in there.
Most likely the DEF request is getting intercepted at two different levels, resulting in the request getting logged twice.
Your problem is a textbook concurrency problem.
You have multiple threads running at the same time that are able to read/write variables.
In order to make sure that these values stay correct you need to add a lock around the code that modifies your variables so that only one thread can modify these variables at any one time.
1) code needs to wait until a method that modifies variables becomes available.
2) when a thread is done modifying a variable and is about to exit the code block it needs to notify the other waiting threads that it is done.
Please read the API and review your code, keeping the above points in mind you should have no problems fixing it.
In my application , I have this logic when the user logins , it will call the below method , with all the symbols the user owns .
public void sendSymbol(String commaDelimitedSymbols) {
try {
// further logic
} catch (Throwable t) {
}
}
my question is that as this task of sending symbols can be completed slowly but must be completed , so is there anyway i can make this as a background task ??
Is this possible ??
please share your views .
Something like this is what you're looking for.
ExecutorService service = Executors.newFixedThreadPool(4);
service.submit(new Runnable() {
public void run() {
sendSymbol();
}
});
Create an executor service. This will keep a pool of threads for reuse. Much more efficient than creating a new Thread each time for each asynchronous method call.
If you need a higher degree of control over your ExecutorService, use ThreadPoolExecutor. As far as configuring this service, it will depend on your use case. How often are you calling this method? If very often, you probably want to keep one thread in the pool at all times at least. I wouldn't keep more than 4 or 8 at maximum.
As you are only calling sendSymbol once every half second, one thread should be plenty enough given sendSymbols is not an extremely time consuming routine. I would configure a fixed thread pool with 1 thread. You could even reuse this thread pool to submit other asynchronous tasks.
As long as you don't submit too many, it would be responsive when you call sendSymbol.
There is no really simple solution. Basically you need another thread which runs the method, but you also have to care about synchronization and thread-safety.
new Thread(new Runnable() {
public void run() {
sendSymbol(String commaDelimitedSymbols);
}
}).start();
Maybe a better way would be to use Executors
But you will need to case about thread-safety. This is not really a simple task.
It sure is possible. Threading is the way to go here. In Java, you can launch a new thread like this
Runnable backGroundRunnable = new Runnable() {
public void run(){
//Do something. Like call your function.
}};
Thread sampleThread = new Thread(backGroundRunnable);
sampleThread.start();
When you call start(), it launches a new thread. That thread will start running the run() function. When run() is complete, the thread terminates.
Be careful, if you are calling from a swing app, then you need to use SwingUtil instead. Google that up, sir.
Hope that works.
Sure, just use Java Threads, and join it to get the results (or other proper sync method, depends on your requirements)
You need to spawn a separate thread to perform this activity concurrently. Although this will not be a separate process, but you can keep performing other task while you complete sending symbols.
The following is an example of how to use threads. You simply subclass Runnable which contains your data and the code you want to run in the thread. Then you create a thread with that runnable object as the parameter. Calling start on the thread will run the Runnable object's run method.
public class MyRunnable implements Runnable {
private String commaDelimitedSymbols;
public MyRunnable(StringcommaDelimitedSymbols) {
this.commaDelimitedSymbols = commaDelimitedSymbols;
}
public void run() {
// Your code
}
}
public class Program {
public static void main(String args[]) {
MyRunnable myRunnable = new MyRunnable("...");
Thread t = new Thread(myRunnable)
t.start();
}
}
My multi-threaded application has a main class that creates multiple threads. The main class will wait after it has started some threads. The runnable class I created will get a file list, get a file, and remove a file by calling a web service. After the thread is done it will notify the main class to run again. My problem is it works for a while but possibly after an hour or so it will get to the bottom of the run method from the output I see in the log and that is it. The Java process is still running but it does not do anything based on what I am looking at in the log.
Main class methods:
Main method
while (true) {
// Removed the code here, it was just calling a web service to get a list of companies
// Removed code here was creating the threads and calling the start method for threads
mainClassInstance.waitMainClass();
}
public final synchronized void waitMainClass() throws Exception {
// synchronized (this) {
this.wait();
// }
}
public final synchronized void notifyMainClass() throws Exception {
// synchronized (this) {
this.notify();
// }
}
I originally did the synchronization on the instance but changed it to the method. Also no errors are being recorded in the web service log or client log. My assumption is I did the wait and notify wrong or I am missing some piece of information.
Runnable Thread Code:
At the end of the run method
// This is a class member variable in the runnable thread class
mainClassInstance.notifyMainClass();
The reason I did a wait and notify process because I do not want the main class to run unless there is a need to create another thread.
The purpose of the main class is to spawn threads. The class has an infinite loop to run forever creating and finishing threads.
Purpose of the infinite loop is for continually updating the company list.
I'd suggest moving from the tricky wait/notify to one of the higher-level concurrency facilities in the Java platform. The ExecutorService probably offers the functionality you require out of the box. (CountDownLatch could also be used, but it's more plumbing)
Let's try to sketch an example using your code as template:
ExecutorService execSvc = Executors.newFixedThreadPool(THREAD_COUNT);
while (true) {
// Removed the code here, it was just calling a web service to get a list of companies
List<FileProcessingTask> tasks = new ArrayList<FileProcessingTask>();
for (Company comp:companyList) {
tasks.add(new FileProcessingTask(comp));
}
List<Future<FileProcessingTask>> results = execSvc.invokeAll(tasks); // This call will block until all tasks are executed.
//foreach Future<FileProcessingTask> in results: check result
}
class FileProcessingTask implements Callable<FileResult> { // just like runnable but you can return a value -> very useful to gather results after the multi-threaded execution
FileResult call() {...}
}
------- edit after comments ------
If your getCompanies() call can give you all companies at once, and there's no requirement to check that list continuously while processing, you could simplify the process by creating all work items first and submit them to the executor service all at once.
List<FileProcessingTask> tasks = new ArrayList<FileProcessingTask>();
for (Company comp:companyList) {
tasks.add(new FileProcessingTask(comp));
}
The important thing to understand is that the executorService will use the provided collection as an internal queue of tasks to execute. It takes the first task, gives it to a thread of the pool, gathers the result, places the result in the result collection and then takes the next task in the queue.
If you don't have a producer/consumer scenario (cfr comments), where new work is produced at the same time that task are executed (consumed), then, this approach should be sufficient to parallelize the processing work among a number of threads in a simple way.
If you have additional requirements why the lookup of new work should happen interleaved from the processing of the work, you should make it clear in the question.
I have developed a JSP web application which, on every request, spawns a new Java Thread. In every newly spawned thread I create a Process using Runtime.exec() and store the process object in an instance variable in thread. I have a requirement in which I have to kill the created subprocess and also stop the thread. So, I overrode the interrupt method in the thread and in the overridden method I'm calling destroy() on already stored Process object in the instance variable. Following is the code:
public class MyThread extends Thread {
private Process subprocess;
#Override
public void run() {
subprocess = Runtime.getRuntime().exec("myprocess.exe");
subprocess.waitFor();
/*
Some more statements
*/
}
#Override
public void interrupt() {
if(subprocess!=null) {
System.out.println("Destroying Process");
subprocess.destroy();
}
super.interrupt();
}
}
Is it illeagal to override interrupt method?
Its important that I kill the created process before I interrupt the thread that creates it. I see that the thread does get interrupted because the statements after waitFor() do not get executed. But, however, destroy() doesnt work (but gets called) and the created "myprocess.exe" completes execution even if I call interrupt() method before its completion. Can someone please help me out with this? What am I missing?
Thanks in advance
It's not illegal to override interrupt, but I wouldn't recommend it. Perhaps a cleaner way to do this would be:
public class MyThread extends Thread {
private Process subprocess;
#Override
public void run() {
subprocess = Runtime.getRuntime().exec("myprocess.exe");
try {
subprocess.waitFor();
}
catch (InterruptedException e) {
subprocess.destroy();
}
/*
Some more statements
*/
}
}
Don't forget that you should also pull data from the subprocess output/error streams, otherwise you might wind up with full buffers and a blocked subprocess. It's OK to read from those streams and discard the data. I suspect the commons-io package has tools to make this a one-liner, otherwise it's a fairly simple method to write yourself.