I have three threads, each thread have to do some manipulation with the instance(q) of same class (Q), periodically (That's why I use Thread.sleep() in the method somecheck). Main task is to make thread execute not at the same time, so at one time can execute only one thread.
I tried to put content of run method each thread into synchronized (q){}, but I do not understand where to put notify and wait methods.
class Q {
boolean somecheck(int threadSleepTime){
//somecheck__section, if I want to stop thread - return false;
try{
Thread.sleep(threadSleepTime);
} catch (InterruptedException e) {
}
return true;
}
}
class threadFirst extends Thread {
private Q q;
threadFirst(Q q){this.q=q;}
public void run(){
do{
//Working with object of class Q
}
while(q.somecheck(10));
}
}
class threadSecond extends Thread {
private Q q;
threadSecond(Q q){this.q=q;}
public void run(){
do{
//Working with object of class Q
}
while(q.somecheck(15));
}
}
class threadThird extends Thread {
private Q q;
threadThird(Q q){this.q=q;}
public void run(){
do{
//Working with object of class Q
}
while(q.somecheck(20));
}
}
class run{
public static void main(String[] args) {
Q q = new Q();
threadFirst t1 = new threadFirst(q);
threadSecond t2 = new threadSecond(q);
threadThird t3 = new threadThird(q);
t1.start();
t2.start();
t3.start();
}
}
You don't need to put any notify() and wait() methods if you use synchronized blocks inside all of the methods, for example:
class threadFirst extends Thread {
...
public void run() {
synchronized (q) {
//your loop here
}
}
...
}
Related
I have two classes, The first one is in charge of creating threads, then those threads need to be notified from the second class
Problem: I cannot find created threads from the second class, getThreadByName() always return null, Any Idea?.
FirstClass
public class class1{
protected void createThread(String uniqueName) throws Exception {
Thread thread = new Thread(new OrderSessionsManager());
thread.setName(uniqueName);
thread.start();
}
}
OrderSessionManager
public class OrderSessionsManager implements Runnable {
public OrderSessionsManager() {
}
#Override
public void run() {
try {
wait();
}catch(Exception e) {
e.printStackTrace();
}
}
SecondClass
public class class2{
protected void notifyThread(String uniqueName) throws Exception {
Thread thread = Utils.getThreadByName(uniqueName);
thread.notify();
}
}
Utils
public class Utils{
public static Thread getThreadByName(String threadName) {
ThreadGroup currentGroup = Thread.currentThread().getThreadGroup();
int noThreads = currentGroup.activeCount();
Thread[] threads = new Thread[noThreads];
currentGroup.enumerate(threads);
List<String>names = new ArrayList<String>();
for (Thread t : threads) {
String tName = t.getName().toString();
names.add(tName);
if (tName.equals(threadName)) return t;
}
return null;
}
}
There are several issues with your code:
1) It breaks Java Code Conventions: class name must start with a
capital letter
2) wait() method must be called by a thread who owns the object's monitor
so you must use something like:
synchronized (this) {
wait();
}
3) notify() method must be called by a thread who owns the object's monitor and by the same object as wait(), in your case OrderSessionsManager's instance.
4) Since you do not specify a ThreadGroup, the thread gets it's ThreadGroup from it's parent. The following code works as expected:
public class Main {
public static void main(String[] args) {
class1 c1 = new class1();
try {
c1.createThread("t1");
} catch (Exception e) {
e.printStackTrace();
}
Thread thread = Utils.getThreadByName("t1");
System.out.println("Thread name " + thread.getName());
}
}
but this happens only because the t1 thread is in the same group as the main thread.
Suppose I have a method called Magic() I want to execute this method with three different thread.
I know how to execute Magic() method with a single thread, but I am confuse, How do I do with three different threads?
Suppose I have a method called Magic() I want to execute this method with three different thread
Create a MagicTask class that represents the task that each Thread will execute and call the magic() method inside run() :
class MagicTask implements Runnable {
public void run() {
magic();
}
public void magic() { //do magic }
}
Then create three threads and pass it the task :
Thread t1 = new Thread(new MagicTask());
Thread t2 = new Thread(new MagicTask());
Thread t3 = new Thread(new MagicTask());
Then start the threads :
t1.start();
t2.start();
t3.start();
Note You can pass the same MagicTask instance to all three Thread instances as well. Remember that if MagicTask has state that can get inconsistent when accessed by different threads, you also need to make your class thread-safe by using intrinsic locking using synchronized or other such constructs which are out of the scope for this answer.
class Multi3 implements Runnable{
public void run(){
System.out.println("thread is running...");
call();
}
void call(){
System.out.println("method call by"+Thread.currentThread().getName());
}
public static void main(String args[]){
Multi3 m1=new Multi3();
Thread t1 =new Thread(m1);
Thread t2 =new Thread(m1);
Thread t3 =new Thread(m1);
t1.start();
t2.start();
t3.start();
}
}
Here Thread t1,t2,t3 are calling the same method call().
If you are using Java 8, function references are straightforward:
public class Main {
public static void magic() {
System.out.println("this is magic");
}
public static void main(final String args[]) {
new Thread(Main::magic).start();
new Thread(Main::magic).start();
new Thread(Main::magic).start();
}
}
And if magic isn't a static method use:
public class Main {
public void magic() {
System.out.println("this is magic");
}
public static void main(final String args[]) {
Main m = new Main();
new Thread(m::magic).start();
new Thread(m::magic).start();
new Thread(m::magic).start();
}
}
You can try Like.
I am dividing the task to different thread
Try your own logic it just a simple even count,
public class CountNumber implements Runnable {
int stop;
int start;
int totalEvenNo;
public CountNumber(int start, int stop)
{
this.start=start;
this.stop=stop;
}
public void run()
{
int total= countEven(start, stop);
System.out.println("Total Even numbers are :"+total);
}
public int countEven(int str,int stp)
{
for(int i=str;i<=stp;i++)
{
if(i%2==0)
{
totalEvenNo +=1;
System.out.println(totalEvenNo);
}
}
return totalEvenNo;
}
}
public class MainClassNumber {
public static void main(String[] args) {
System.out.println("Spawaning Thread.........");
Thread t1 = new Thread(new CountNumber(0, 500000));
Thread t2 = new Thread(new CountNumber(500001, 2000000));
Thread t3 = new Thread(new CountNumber(2000001, 5000000));
Thread t4 = new Thread(new CountNumber(5000001, 10000000));
Thread t5 = new Thread(new CountNumber(10000001, 20000000));
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
}
}
Call it directly like magic(); And for better result synchronize that method like below
public synchronized void magic(){
//your code
}
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
class WorkerThread implements Runnable {
public void run() {
Magic();
}
private void Magic() {
// consider synchronizing this method, but if you do method will be accessable by one thread at a time.
}
}
public class TestThreadPool {
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(3)
for (int i = 0; i < 3; i++) {
Runnable worker = new WorkerThread();
executor.execute(worker);
}
executor.shutdown();
while (!executor.isTerminated()) {}
}
}
}
Since you are using a Thread, the code further below might give results like:
waiting...One
waiting...Three
waiting...Two
Notified...Two
Notified...Three
Then the code is running until it hits a dead lock. Why is Notified...One missing in the output above? Needs explanation ... (You can get similar result as above when executing following code several time)
class A {
synchronized void waitThread(String threadName) {
System.out.println("waiting..." + threadName);
try {
wait();
} catch(InterruptedException e) { }
System.out.println("Notified..." + threadName);
}
synchronized void notifyThread() {
notifyAll();
}
}
class T1 extends Thread {
A a;
T1(A r, String n) {
a = r;
setName(n);
}
public void run() {
a.waitThread(getName());
}
}
class T2 extends Thread {
A a;
T2(A r, String n) {
a = r;
setName(n);
}
public void run() {
a.notifyThread();
}
}
public class DemoWait {
public static void main(String args[]) {
A a1 = new A();
T1 t1 = new T1(a1,"One");
T1 t2 = new T1(a1,"Two");
T1 t3 = new T1(a1,"Three");
t1.start();
t2.start();
t3.start();
T2 t = new T2(a1,"Four");
t.start();
}
}
You simply have a race condition. It's possible that the thread referenced by the variable t executes notifyAll() before the thread referenced by t1 executes the waitThread(..) method. This is not deadlock. Some of your waits just happen after your notifyAll().
You are facing the problem of Spurious wakeup.So what is happening that the thread which is notifying the all other thread might be call earlier of other thread and after that other thread will run and wait for the wake up.Because of spurious wake up some thread complete.
Change your code...
class A{
boolean flag=true;
synchronized void waitThread(String threadName){
System.out.println("waiting..."+threadName);
try{
while(flag){
wait();
}
}catch(InterruptedException e){ }
System.out.println("Notified..."+threadName);
}
synchronized void notifyThread(){
flag=false;
notifyAll();
} }
Assume that one thread prints "Hello" and another prints "World". I have done it successfully for one time, as follows:
package threading;
public class InterThread {
public static void main(String[] args) {
MyThread mt=new MyThread();
mt.start();
synchronized(mt){
System.out.println("Hello");
try {
mt.wait();
i++;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class MyThread extends Thread{
public void run(){
synchronized(this){
System.out.println("World!");
notify();
}
}
}
How do I do it for multiple time printing, say for 5 times? I tried putting for loop around the synchronized block, but of no use.
Here being two interdependent threads, we need two synchronizing objects. they could be one of many things. one integer, another object; one Boolean another object; both object; both semaphores and so on. the synchronization technique could be either Monitor or Semaphore any way you like, but they have to be two.
I have modified your code to use semaphore instead of Monitor. The Semaphore works more transparently. You can see the acquire and release happening. Monitors are even higher constructs. Hence Synchronized works under the hood.
If you are comfortable with the following code, then you can convert it to use Monitors instead.
import java.util.concurrent.Semaphore;
public class MainClass {
static Semaphore hello = new Semaphore(1);
static Semaphore world = new Semaphore(0);
public static void main(String[] args) throws InterruptedException {
MyThread mt=new MyThread();
mt.hello = hello;
mt.world = world;
mt.start();
for (int i=0; i<5; i++) {
hello.acquire(); //wait for it
System.out.println("Hello");
world.release(); //go say world
}
}
}
class MyThread extends Thread{
Semaphore hello, world;
public void run(){
try {
for(int i = 0; i<5; i++) {
world.acquire(); // wait-for it
System.out.println(" World!");
hello.release(); // go say hello
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class ThreadSeq {
Object hello = new Object();
Object world = new Object();
public static void main(String[] args) throws InterruptedException {
for(int i=0; i<6;i++){
Runnable helloTask = new Runnable(){
#Override
public void run(){
new ThreadSeq().printHello();
}
};
Runnable worldTask = new Runnable(){
#Override
public void run(){
new ThreadSeq().printWorld();
}
};
Thread t1 = new Thread(helloTask);
Thread t2 = new Thread(worldTask);
t1.start();
t1.join();
t2.start();
t2.join();
}
}
public void printHello(){
synchronized (hello) {
System.out.println("Hello");
}
}
public void printWorld(){
synchronized (world) {
System.out.println("World");
}
}
}
The goal here is to synchronize threads so that when one is done it notify the other. If I have to make it, it would be 2 threads executing the same code with different data. Each thread has its own data ("Hello" and true to T1, "World" and false to t2), and share a variable turn plus a separate lock object.
while(/* I need to play*/){
synchronized(lock){
if(turn == myturn){
System.out.println(mymessage);
turn = !turn; //switch turns
lock.signal();
}
else{
lock.wait();
}
}
}
Before you start trying to get it to work five times you need to make sure it works once!
Your code is not guaranteed to always print Hello World! - the main thread could be interrupted before taking the lock of mt (note that locking on thread objects is generally not a good idea).
MyThread mt=new MyThread();
mt.start();
\\ interrupted here
synchronized(mt){
...
One approach, that will generalise to doing this many times, is to use an atomic boolean
import java.util.concurrent.atomic.AtomicBoolean;
public class InterThread {
public static void main(String[] args) {
int sayThisManyTimes = 5;
AtomicBoolean saidHello = new AtomicBoolean(false);
MyThread mt=new MyThread(sayThisManyTimes,saidHello);
mt.start();
for(int i=0;i<sayThisManyTimes;i++){
while(saidHello.get()){} // spin doing nothing!
System.out.println("Hello ");
saidHello.set(true);
}
}
}
class MyThread extends Thread{
private final int sayThisManyTimes;
private final AtomicBoolean saidHello;
public MyThread(int say, AtomicBoolean said){
super("MyThread");
sayThisManyTimes = say;
saidHello = said;
}
public void run(){
for(int i=0;i<sayThisManyTimes;i++){
while(!saidHello.get()){} // spin doing nothing!
System.out.println("World!");
saidHello.set(false);
}
}
}
This is in C:
#include <stdio.h>
#include <pthread.h>
pthread_mutex_t hello_lock, world_lock;
void printhello()
{
while(1) {
pthread_mutex_lock(&hello_lock);
printf("Hello ");
pthread_mutex_unlock(&world_lock);
}
}
void printworld()
{
while(1) {
pthread_mutex_lock(&world_lock);
printf("World ");
pthread_mutex_unlock(&hello_lock);
}
}
int main()
{
pthread_t helloThread, worldThread;
pthread_create(&helloThread,NULL,(void *)printhello,NULL);
pthread_create(&helloThread,NULL,(void *)printhello,NULL);
pthread_join(helloThread);
pthread_join(worldThread);
return 0;
}
There are two thread and both has its own data ("Hello" and true to ht, "World" and false to wt), and share a variable objturn.
public class HelloWorldBy2Thread {
public static void main(String[] args) {
PrintHelloWorld hw = new PrintHelloWorld();
HelloThread ht = new HelloThread(hw);
WorldThread wt = new WorldThread(hw);
ht.start();
wt.start();
}
}
public class HelloThread extends Thread {
private PrintHelloWorld phw;
private String hello;
public HelloThread(PrintHelloWorld hw) {
phw = hw;
hello = "Hello";
}
#Override
public void run(){
for(int i=0;i<10;i++)
phw.print(hello,true);
}
}
public class WorldThread extends Thread {
private PrintHelloWorld phw;
private String world;
public WorldThread(PrintHelloWorld hw) {
phw = hw;
world = "World";
}
#Override
public void run(){
for(int i=0;i<10;i++)
phw.print(world,false);
}
}
public class PrintHelloWorld {
private boolean objturn=true;
public synchronized void print(String str, boolean thturn){
while(objturn != thturn){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.print(str+" ");
objturn = ! thturn;
notify();
}
}
In simple way we can do this using wait() and notify() without creating any extra object.
public class MainHelloWorldThread {
public static void main(String[] args) {
HelloWorld helloWorld = new HelloWorld();
Thread t1 = new Thread(() -> {
try {
helloWorld.printHello();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
Thread t2 = new Thread(() -> {
try {
helloWorld.printWorld();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
// printHello() will be called first
t1.setPriority(Thread.MAX_PRIORITY);
t1.start();
t2.start();
}
}
class HelloWorld {
public void printHello() throws InterruptedException {
synchronized (this) {
// Infinite loop
while (true) {
// Sleep for 500ms
Thread.sleep(500);
System.out.print("Hello ");
wait();
// This thread will wait to call notify() from printWorld()
notify();
// This notify() will release lock on printWorld() thread
}
}
}
public void printWorld() throws InterruptedException {
synchronized (this) {
// Infinite loop
while (true) {
// Sleep for 100ms
Thread.sleep(100);
System.out.println("World");
notify();
// This notify() will release lock on printHello() thread
wait();
// This thread will wait to call notify() from printHello()
}
}
}
}
I have 2 classes. One method of the class calls the other class' method, but it has to wait until the method finishes to proceed to the execution of the rest of the code.
This is a rough code of what I'm trying to make. And I know this doesn't work.
public class Example
{
Thread thread;
public Example(Thread thread)
{
this.thread = thread;
}
public void doSomethingElse()
{
System.out.println("Do something else");
thread.notify();
}
}
public class Example2
{
Thread thread;
Example example;
public Example2()
{
example = new Example(thread);
thread = new Thread()
{
public void run()
{
example.doSomethingElse();
try {
this.wait();
} catch (InterruptedException ex) {
}
System.out.println("Do something");
}
};
}
public void doSomething()
{
thread.run();
}
}
Now do you know how to make this right?
Not sure if your constrained to using this particular approach (wait/notify) however a better approach is taking advantage of the Java Concurrency API
public class ExampleCountDownLatch
{
public void doSomething () throws InterruptedException
{
final CountDownLatch latch = new CountDownLatch(1);
Thread thread = new Thread()
{
public void run ()
{
System.out.println("do something");
latch.countDown();
}
};
System.out.println("waiting for execution of method in your example class");
thread.start();
// wait for reasonable time otherwise kill off the process cause it took
// too long.
latch.await(3000, TimeUnit.MILLISECONDS);
// now I can do something from your example 2
System.out.println("now i can execute from example 2 do something else");
}
}
Anyway just another approach if you had an option.
UPDATE:
Here is a blog about this very topic.
Couple of points :
you should acquire lock before calling wait or notify method. The
lock must be on same object. In code you are calling wait on example2
object but calling notify on different object.
thread.run() means calling run method of thread object, its not
creating new thread its same as example.doSomething(). When you
create thread start that thread by calling start method.
Here is my implementation
class Example implements Runnable
{
public void run()
{
doSomething();
}
public void doSomething(){
synchronized(this){
System.out.println("Do something else");
try{
Thread.sleep(1000);
this.notify();
}catch (InterruptedException ignore) {}
}
}
}
class Example2 implements Runnable
{
Thread thread;
Example example;
public Example2(Example example){
this.example = example;
}
public void run(){
doSomething();
}
public void doSomething(){
synchronized(example){
System.out.println("waiting for example 1 to complete");
try{
example.wait();
}catch (InterruptedException ignore) {}
}
System.out.println("Do something");
}
}
public class Entry{
public static void main(String[] args){
Example example = new Example();
Example2 obj = new Example2(example);
Thread t = new Thread(obj);
t.start();
Thread t2 = new Thread(example);
t2.start();
}
}
In code Thread.sleep(1000); statement is not needed.
Here is one more implementation using join method
class Example implements Runnable
{
public void run()
{
doSomething();
}
public void doSomething(){
System.out.println("Do something else");
try{
Thread.sleep(1000);
}catch (InterruptedException ignore) {}
}
}
class Example2 implements Runnable
{
Thread thread;
Example example;
public Example2(Example example){
this.example = example;
}
public void run(){
System.out.println("waiting for example 1 to complete");
Thread t = new Thread(example);
try{
t.start();
t.join();
}catch(InterruptedException ie){
}
doSomething();
}
public void doSomething(){
System.out.println("Do something");
}
}
public class Entry{
public static void main(String[] args){
Example example = new Example();
Example2 obj = new Example2(example);
Thread t = new Thread(obj);
t.start();
}
}