How can I call a same method with three different thread - java

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()) {}
}
}
}

Related

Why my synchronized method not working properly?

I have this synchronized method that prints counter, I have 4 Threads so I am expecting final value of my counter to be 400000 as my counter is a static variable.
but every time I run my code, it is giving me different values of counter.
Following is my code:
class MyThread implements Runnable{
private static int counter=1;
#Override
public void run() {
try {
this.syncMethod();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public synchronized void syncMethod() throws InterruptedException{
for(int i=0;i<100000;i++){
System.out.println(Thread.currentThread().getName()+" : "+counter++);
}
}
}
public class MyController {
public static void main(String[] args) throws InterruptedException {
Runnable r1=new MyThread();
Runnable r2=new MyThread();
Runnable r3=new MyThread();
Runnable r4=new MyThread();
Thread t1;
Thread t2;
Thread t3;
Thread t4;
t1=new Thread(r1,"Thread 1");
t2=new Thread(r2,"Thread 2");
t3=new Thread(r3,"Thread 3");
t4=new Thread(r4,"Thread 4");
t2.start();
t1.start();
t3.start();
t4.start();
}
}
The variable is static, but the method that you synchronized is not static. This means that it will acquire the monitor on the current instance, and every thread has a different current instance.
A simple solution is to make the syncMethod method static as well; in that case, it will take a lock on the monitor that is shared by all instances of the MyThread class:
public static synchronized void syncMethod()
Erwin Bolwidt's answer is right to solve your problem. As another way to increment a static shared counter in multiple threads safely, you can turn to AtomicLong.
Define it as this:
private static AtomicLong counter = new AtomicLong();
Increment it as:
counter.getAndIncrement();
And in the end, get the result:
counter.get();
synchronised key word in non static methods means exactly synchronize me for this methods : this two code a striclty equivalent :
public synchronised void dojob(){
//the job to do
}
et
public void dojob(){
synchronised (this){
//the job to do
}
}
in your case your synchronized methods are synchronizing on different object (t1,t2,t3 and t4) so didn't block them each other . the best solution is thaat your thread will use a common object to synchronized each other. an other point it alway better to get its thread back to do this call join here is a code to do what you want with this 2 fixes
class MyThread implements Runnable {
public static class JobDoer {
public synchronized void syncMethod() throws InterruptedException {
for (int i = 0; i < 100000; i++) {
System.out.println(Thread.currentThread().getName() + " : " + counter++);
}
}
}
private static int counter = 1;
public MyThread(JobDoer doer) {
this.doer = doer;
}
private JobDoer doer;
#Override
public void run() {
try {
doer.syncMethod();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws InterruptedException {
JobDoer doer = new JobDoer();
Thread t1 = new Thread(new MyThread(doer), "Thread 1");
Thread t2 = new Thread(new MyThread(doer), "Thread 2");
Thread t3 = new Thread(new MyThread(doer), "Thread 3");
Thread t4 = new Thread(new MyThread(doer), "Thread 4");
t2.start();
t1.start();
t3.start();
t4.start();
t1.join();
t2.join();
t3.join();
t4.join();
}
}

Defining two different Threads in java

Im new to Threads and I was wondering how could I define what two or more different Threads do in a Java program. Do i define them all in the same public void run method? If so, how do I do it? I would like the Threat t1 to invoke the increment method, t2 to invoke the decrement method and both of them to call the value method
Here's the code example:
package interference;
/**
*
* #author rodrigopeniche
*/
public class Interference implements Runnable{
/**
* #param args the command line arguments
*
*/
Counter counter1= new Counter();
class Counter{
private int c= 0;
public void increment()
{
c++;
}
public void decrement()
{
c--;
}
public int value()
{
return c;
}
}
public static void main(String[] args) {
// TODO code application logic here
Thread t1= new Thread(new Interference());
Thread t2= new Thread(new Interference());
t1.start();
t2.start();
}
#Override
public void run() {
counter1.increment();
counter1.decrement();
counter1.value();
}
}
You can set names to threads like thread1, thread2. After that, in the run method, check the name of the thread currently running and do the necessary action.
You have to add a while loop inside the run method if you need to run it longer.
public static void main(String[] args) {
Interference interference = new Interference();//create a new Interference object
Thread t1 = new Thread(interference, "thread1");//pass the runnable interference object and set the thread name
Thread t2 = new Thread(interference, "thread2");//pass the runnable interference object and set the thread name
t1.start();
t2.start();
}
#Override
public void run() {
while (true) {//to run it forever to make the difference more visual
String threadName = Thread.currentThread().getName();//get the current thread's name
if (threadName.equals("thread1")) {//if current thread is thread1, increment
counter1.increment();
} else if (threadName.equals("thread2")) {//if current thread is thread2, decrement
counter1.decrement();
}
System.out.println(counter1.value());//print the value
}
}
When you run the code, you can see count is going up and down in a random manner.
In your current code, counter1 is an instance variable of class Interference. You create 2 instances of Interference and then use them to create two Thread objects. When the threads start to run, each Thread is actually working on it's own copy of counter1. I think that may not be what you expect.
package interference;
public class Interference {
static class Counter {
private int c = 0;
public void increment() {
c++;
}
public void decrement() {
c--;
}
public int value() {
return c;
}
}
public static void main(String[] args) {
Counter counter = new Counter();
Thread t1 = new Thread(new Runnable() {
public void run() {
counter.increment();
System.out.println(counter.value());
}
});
Thread t2 = new Thread(new Runnable() {
public void run() {
counter.decrement();
System.out.println(counter.value());
}
});
t1.start();
t2.start();
}
}

Threads execute not at the same time

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
}
}
...
}

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.

Thread Dependency Java

I have a main class which spawns a thread, let's call them MainClass and MyThread.
public class MainClass extends javax.swing.JFrame {
int sharedVariable;
MyThread threadInstance;
public MainClass (){
sharedVariable = 2;
threadInstance = new MyThread(this);
threadInstance.run();
}
public int getSharedVariable(){ return sharedVariable; }
public static void main(String[] args){
//begin main class
}
}
public class MyThread implements Runnable {
MainClass class;
public MyThread(MainClass main_class){
this.main_class= main_class;
}
#Override
public run(){
while(this.main_class is still active){
//grab status of sharedVariable and wait for x amount of time.
}
}
}
The problem is I do not know how to implement the while condition which checks if the MainClass instance is still alive and if it is, it has to use the this.main_class.getSharedVariable() to get the value of sharedVariable, then wait for x amount of time. MainClass has the main method .
I would recommend holding onto the Thread instance and then calling threadInstance.interrupt() right before the main(...) method exits.
Something like:
public static void main(String[] args){
MainClass mainClass = new MainClass();
try {
...
// do main stuff here
...
} finally {
mainClass.threadInstance.interrupt();
}
}
Then in your thread you'd do:
while(!Thread.currentThread().isInterrupted()){
...
}
You'd also want to handle InterruptedException correctly:
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// always a good pattern to re-interrupt the thread here
Thread.currentThread().interrupt();
// if we are interrupted quit
return;
}
Btw, it is very bad form to leak the instance of an object during construction to another thread:
new MyThread(this);
See here: Why shouldn't I use Thread.start() in the constructor of my class?
Also, you aren't starting a thread when you call threadInstance.run();. You are just running it in the current thread. You should use threadInstance.start() but not inside of the constructor like that.
You can use CountDownLatch which is very convenient for such tasks as waiting other threads to finish some activity (you can change Thread.sleep(...) argument in main to, say, 12000L and see what happens):
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
class OtherThread extends Thread {
private final CountDownLatch sharedLatch;
OtherThread(CountDownLatch sharedLatch) {
this.sharedLatch = sharedLatch;
}
#Override
public void run() {
boolean wokenByMain = false;
try {
wokenByMain = sharedLatch.await(10000L, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
return; // or not return, whatever makes more sense in your case
}
System.out.println("heh: " + wokenByMain);
}
}
class SOSample {
public static void main(String[] args) throws InterruptedException {
CountDownLatch latch = new CountDownLatch(1);
OtherThread otherThread = new OtherThread(latch);
otherThread.start();
System.out.println("Scheduled other thread to be started");
Thread.sleep(1000L);
System.out.println("going to release other thread");
latch.countDown();
}
}
public class MainClass extends JFrame implements Runnable {
public static void main(String [] args) {
final Thread t=new Thread(new MainClass() {
public void run(){
//something
});
Thread t2=new Thread(new MyThread() {
public void run() {
while(t.isAlive) {
//something
}
}
});
}
}

Categories