How can I ensure thread safety in the following context? - java

I have a method called processOutbox. I want it to be thread safe. I don't want another thread to call this method while one thread is at it. I have implemented it the following way. Have I done it correctly? Are there any loopholes in my implementation? If there are any, then please advice on how I can resolve it.
this.start();
outboxLock.lock();
timer = new Timer();
try{
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
processOutbox();
}
}, 0, period);
} finally{
outboxLock.unlock();
}

If you want to make your method processOutbox, you should use the keyword synchronized:
public class YourClass{
public synchronized void processOutbox(){
//do all you want
}
}
More info at:https://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html
If in your code you have an instance of YourClass called for example myInstance , all calls to processOutbox() will be thread safe because they will be locked at instance level.
For example:
YourClass myInstance = new YourClass();
Thread thread1 = new Thread(){
public void run(){
myInstance.processOutbox();
}
}
Thread thread2 = new Thread(){
public void run(){
myInstance.processOutbox();
}
}
thread1.start();
thread2.start();
Here thead2 will be waiting until thread1 finishes the call to "processOutbox"
But for example:
YourClass myInstance = new YourClass();
YourClass myInstance2= new YourClass();
Thread thread1 = new Thread(){
#Override
public void run(){
myInstance.processOutbox();
}
};
Thread thread2 = new Thread(){
#Override
public void run(){
myInstance2.processOutbox();
}
}
thread1.start();
thread2.start();
thead2 will NOT wait because they are calling the method on different instances.
Someone specifically asked about using ReentrantLock -- So I'm adding that response on to this one, because this one is correct.
public class YourClass {
private Lock outboxLock = new ReentrantLock();
public void processOutbox() {
outboxLock.lock()
try {
// do stuff
} finally {
outboxLock.unlock()
}
}
}
I mention this specifically because you can also do things, where you keep other threads out of the lock without causing them to block by using tryLock instead.
public class YourClass {
private Lock outboxLock = new ReentrantLock();
public void processOutbox() {
if( outboxLock.tryLock() ) {
try {
// do stuff
} finally {
outboxLock.unlock()
}
}
}
}

Use a CountDownLatch for synchronization.

Related

Any way to stop a thread that implements Runnable using a boolean , without extending Thread ?

Consider the code :
public class MyThread implements Runnable{
private volatile static boolean running = true;
public void stopThread()
{
running = false;
}
#Override
public void run() {
while (running)
{
try {
System.out.println("Sleeping ...");
Thread.sleep(15000);
System.out.println("Done sleeping ...");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args)
{
MyThread thread = new MyThread();
thread.run();
}
}
Is it possible to stop a thread that implements Runnable with a boolean , without extending Thread ?
Is it possible to stop a thread that implements Runnable
A class that implements Runnable is not a thread. It is just a plain class with no magic to it, declaring a single void run() method. Your example therefore doesn't start any threads.
So instead of misleadingly naming your class MyThread, you should name it MyTask and pass it to a Thread constructor:
final MyTask task = new MyTask();
new Thread(task).start();
Thread.sleep(2000);
task.stopRunning(); // renamed from stopThread
Also, do make the running flag an instance variable. Each MyTask should have its own running flag.
MyThread myt = new MyThread();
(new Thread(myt)).start();
Later call
myt.stopThread();
Sounds like you want to use the built in interrupt mechanism which does basically the same thing you're trying to implement.
public class MyRunnable implements Runnable{
#Override
public void run() {
while (!Thread.interrupted())
{
try {
System.out.println("Sleeping ...");
Thread.sleep(15000);
System.out.println("Done sleeping ...");
} catch (InterruptedException e) {
// This means someone called thread.interrupt() while you were sleeping
return;
}
}
}
public static void main(String[] args)
{
// You didn't extend Thread, you implemented Runnable:
Thread thread = new Thread(new MyRunnable());
// thread.run() is synchronous, for this (the main) thread to continue use:
thread.start();
...
thread.interrupt();
}
}
Yes, you can. The Runnable code you have above is almost correct, but you should probably make the running field not static. The way you create your Thread needs an extra step, though. It should be:
Runnable r = new MyThread(); // MyThread already implements Runnable instead of extending Thread, so that's correct.
Thread t = new Thread(r);
t.start(); // not t.run() or r.run(), that would execute the code synchronously
r.stopThread(); // when needed

Java: IllegalMonitorStateException on notify()

I am trying to call wait() function on the "slp" object, then after 1000 mills wake it up, but instead of message "Finished ..." I get an "IllegalMonitorStateException" error, after calling notify()
class Class1 extends Thread{
boolean newTxt = false;
private Sleep slp = null;
synchronized public void put(Sleep slp)
{
thus.slp = slp;
try{ slp.wait();}catch(Exception x){}
}
synchronized public void wakeup()
{
slp.notify();
}
public void run()
{
while(slp == null );
try{ sleep(1000);}catch(Exception x){}
wakeup();
}
}
class Sleep extends Thread {
Class1 t;
Sleep(Class1 t) {
this.t=t;
}
public void run() {
System.out.println("Started");
t.put(this);
System.out.println("Finished after 1000 mills");
}
}
public class Koord {
public static void main(String[] args) {
Class1 t = new Class1();
Sleep t1 = new Sleep(t);
t1.start();
t.start();
}
}
You need to be the "owner of the object's monitor" to be able to call notify on it.Your methods are all synchronized on this and you notify() on other objects. Just call wait() and notify().
IllegalMonitorStateException ,Thrown to indicate that a thread has attempted to wait on an object's monitor or to notify other threads waiting on an object's monitor without owning the specified monitor.

2 Threads to execute 2 similar jobs

I have 2 jobs I want to execute in JAVA. I have:
public static void main(String[] args)
{
takeInfofromDB();
doSomeLongCalculationsWithThatData();
takeInfofromDB2();
doSomeLongCalculationsWithThatData2();
GenerateAnswerFromBothAnswers();
}
Is it possible to somehow put takeInfofromDB(); and doSomeLongCalculationsWithThatData(); in 2 Threads? And GenerateAnswerFromBothAnswers(); can't execute while at least one is still working?
Like this...
public static void main(String[] args)
{
Thread t1 = new Thread(new Runnable() {
public void run() {
takeInfofromDB();
doSomeLongCalculationsWithThatData();
}});
Thread t2 = new Thread(new Runnable() {
public void run() {
takeInfofromDB2();
doSomeLongCalculationsWithThatData2();
}});
t1.start();
t2.start();
t1.join();
t2.join();
GenerateAnswerFromBothAnswers();
}
For a very simple lightweight approach, try the following code. However you may want to read more about Threads and eventually Executors: http://docs.oracle.com/javase/tutorial/essential/concurrency/
Thread thread1 = new Thread() {
private Object result;
#Override
public void run() {
takeInfofromDB();
result = doSomeLongCalculationsWithThatData();
}
public Object getResult() {
return result;
}
}
Thread thread2 = new Thread() {
private Object result;
#Override
public void run() {
takeInfofromDB2();
result = doSomeLongCalculationsWithThatData2();
}
public Object getResult() {
return result;
}
}
thread1.start();
thread2.start();
thread1.join();
thread2.join();
Object result1 = thread1.getResult();
Object result2 = thread2.getResult();
GenerateAnswerFromBothAnswers(result1, result2);
You shouldn't run this code as is (I haven't tested it, and weird things could happen if you call getResult before join), but it should serve as a starting point for how to use threads in a basic way.

Java and 2 threads

I am trying to learn Java's threads in order to do an assignment, but I do not understand how I can make each thread to do its own code. I also get an error:
Program.java:1: error: Program is not abstract and does not override abstract me
thod run() in Runnable
public class Program implements Runnable {
^
1 error
Because it is required by the assignment, I have to do everything within the same file, so I tried the code below:
public class Program implements Runnable {
Thread thread1 = new Thread () {
public void run () {
System.out.println("test1");
}
};
Thread thread2 = new Thread () {
public void run () {
System.out.println("test2");
}
};
public void main (String[] args) {
thread1.start();
thread2.start();
}
}
Could you please fix it for me and show how to have 2 threads which do different tasks from each other? I have already seen examples that print threads' names, but I did not find them helpful.
Thank you.
Your Program class is defined as implementing the Runnable interface. It therefore must override and implement the run() method:
public void run () {
}
Since your two Thread objects are using anonymous inner Runnable classes, you do not need and your should remove the implements Runnable from your Program class definition.
public class Program {
...
try this:
class Program {
public static void main(String[] args) {
Thread thread1 = new Thread() {
#Override
public void run() {
System.out.println("test1");
}
};
Thread thread2 = new Thread() {
#Override
public void run() {
System.out.println("test2");
}
};
thread1.start();
thread2.start();
}
Or you can create a separate class implementing Runnable and ovverriding method run().
Then in main method create an instance of Thread with you class object as argument :
class SomeClass implements Runnable {
#Override
run(){
...
}
}
and in main:
Thread thread = new Thread(new SomeClass());
When you implement an interface (such as Runnable) you must implement its methods, in this case run.
Otherwise for your app to compile and run just erase the implements Runnable from your class declaration:
public class Program {
public void main (String[] args) {
Thread thread1 = new Thread () {
public void run () {
System.out.println("test1");
}
};
Thread thread2 = new Thread () {
public void run () {
System.out.println("test2");
}
};
thread1.start();
thread2.start();
}
}

Running two functions with threading

I have a class with name Socket that have tow function for example func1 and func2
fucn1() {
while(true) {
...
}
}
fucn2() {
while(true) {
...
}
}
I want two of them run with thread in a time and concurrently. how can i do that??
class socket implement Runnable {
public void run() {
func1();
func2();
}
}
In this code only first function is executed not second. How can i do for concurrently run both of them?
My Suggestion is :
Instead of making socket Class Runnable,
Create two Runnable threads as in my example below and call your functions from there. And start these two threads from your Socket class.
class Socket{
private void startThreads() {
new Thread(new Th1()).start();
new Thread(new Th2()).start();
}
}
class Th1 implements Runnable {
#Override
public void run() {
fucn1();
}
}
class Th2 implements Runnable {
#Override
public void run() {
fucn2();
}
}
You can run them concurrently like this:
// start a thread for func1
Thread t1 = new Thread(new Runnable() {
public void run() {
func1();
}
});
t1.start();
// func2 will run in parallel on the main thread
func2();
t1.join(); // if you want to wait for func1 to finish.
You haven't given any details, so I'm assuming they have no side-effects.
If you want to run the two functions concurrently, spawn two threads and run each function in its own thread.
That's precisely what threads are for.
You need to create two threads for this scenario.
class socket implement runable
{
boolean condition;
public socket(boolean condition){
this.condition = condition;
}
public void run()
{
if(condition == true){
func1();
}else{
func2();
}
}
}
Thread t1 = new Thread(new Socket(true));
Thread t1 = new Thread(new Socket(false));
t1.start();
t2.start();
In addition to this you need to yield control in each method just to make sure that every thread will get fair chance to run.

Categories