Let's suppose I have this class:
public class Myclass {
method1();
method2();
method3();
}
I want to know if there's a way to run all 3 methods in different threads simultaneously.
Is there a way to create a class MyThread :
public class MyThread{
//implementation
}
in way that it can accept as a parameter myclass::method1()
so that my main function looks something like this:
public static void main(String[] args) {
Myclass myclass = new Myclass();
MyThread mythread1 = new MyThread();
MyThread mythread2 = new MyThread();
MyThread mythread3 = new MyThread();
mythread1(myclass.method1());
mythread2(myclass.method2());
mythread3(myclass.method3());
}
I want mythread() to RUN method() in a thread and NOT use the output of it in a thread.
public class HelloRunnable implements Runnable {
private MyClass myClass;
private boolean execMethod1;
private boolean execMethod2;
private boolean execMethod3;
public HelloRunnable(MyClass myClass, boolean execMethod1, boolean execMethod2, boolean execMethod3) {
this.myClass = myClass;
this.execMethod1 = execMethod1;
this.execMethod2 = execMethod2;
this.execMethod3 = execMethod3;
}
public void run() {
if(execMethod1) myClass.method1();
else if(execMethod2) myClass.method2();
else if(execMethod3) myClass.method3();
}
public static void main(String args[]) {
MyClass myClass = new MyClass();
(new Thread(new HelloRunnable(myClass, true, false, false))).start();
(new Thread(new HelloRunnable(myClass, false, true, false))).start();
(new Thread(new HelloRunnable(myClass, false, false, true))).start();
}
}
If you're using Java 8 you can do this sort of thing:
public static void main(String[] args) {
new Thread(MyClass::method1).start();
new Thread(MyClass::method2).start();
new Thread(MyClass::method2).start();
}
In Java 7 and below there's more to the syntax:
public static void main(String[] args) {
new Thread (new Runnable () {
#Override
public void run ()
{
method1 ();
}
}).start();
}
I've only shown one method for brevity - you must repeat everything from new Thead through start() for each method you want to call.
Related
I'm trying to create two classes that extends from Thread, I know how to create one class.
public class Main {
class Thred1 extends Thread {
public void run() {
System.out.println("I'm watching a video...");
}
}
class Thred2 extends Thread {
public void run() {
System.out.println("I'm eating...");
}
}
public static void main (String[] args) {
Thred1 t11 = new Thred1();
Thred2 t12 = new Thred2();
t11.start();
t12.start();
}
}
And got Main.java:15: error: non-static variable this cannot be referenced from a static context
Is there better way to implement my idea?
Your problem is with inner classes and not with threads , try to put all this code in the same file Main.java :
class Thred1 extends Thread {
public void run() {
System.out.println("I'm watching a video...");
}
}
class Thred2 extends Thread {
public void run() {
System.out.println("I'm eating...");
}
}
public class Main {
public static void main (String[] args) {
Thred1 t11 = new Thred1();
Thred2 t12 = new Thred2();
t11.start();
t12.start();
}
}
Another possible solution is to use static classes instead of the member inner classes used in your code :
public class Main {
static class Thred1 extends Thread {
public void run() {
System.out.println("I'm watching a video...");
}
}
static class Thred2 extends Thread {
public void run() {
System.out.println("I'm eating...");
}
}
public static void main(String[] args) {
Thred1 t11 = new Thred1();
Thred2 t12 = new Thred2();
t11.start();
t12.start();
}
}
Or simply you can use Lambda expression , Thread class have a constructor who accept a Runnable as parameter , Runnable is a functional interface so you can pass a Lambda expression as argument like that :
public class Main {
public static void main(String[] args) {
Thread t11 = new Thread(()->System.out.println("I'm watching a video..."));
Thread t12 = new Thread(()->System.out.println("I'm eating..."));
t11.start();
t12.start();
}
}
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()) {}
}
}
}
I stripped everything out to see if I could narrow down my problem and figure it out but I'm embarrassed to say I'm still stumped. Can someone please explain to me why my IDE cannot resolve 'start'? I'm sure it's a stupid mistake :(
public class main {
Thread messageThread = new Thread(new MessageLoop());
messageThread.start();
class MessageLoop implements Runnable {
public void run(){
//Do stuff here
}
}
}
Instead of defining your class in your method body. Java variable names start with a lower case letter by convention. Comments start with // not \\. I think you wanted something like
public static void main(String[] args) {
Thread messageThread = new Thread(new MessageLoop());
messageThread.start();
}
static class MessageLoop implements Runnable {
public void run() {
// Do stuff here
}
}
Use following approaches.
Approach1
public static void main(String[] args) {
Thread MessageThread = new Thread(new MessageLoop());
MessageThread.start();
}
static class MessageLoop implements Runnable {
public void run(){
System.out.println("helllo");
}
}
Approach 2
public static void main(String[] args) {
Thread MessageThread2 = new Thread(new Runnable(){
public void run(){
System.out.println("helllo2");
}
});
MessageThread2.start();
}
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
}
}
});
}
}
I have a function that needs to be called once a boolean variable is true. I tried using a while loop in a thread but it doesn't work. Here is what I've tried:
public class MyRunnable implements Runnable {
public void run() {
while (true) {
if (conditions == true) {
System.out.println("second");
break;
}
}
}
public static void main(String args[]) {
boolean condition = false;
(new Thread(new MyRunnable())).start();
System.out.println("first\n");
// set conndition to true
condition = true;
}
}
The result shoud be:
first
second
Do not busy-wait for such conditions. Use a blocking idiom. For your simple case you would get away with a new CountDownLatch(1). First, here's your code, but fixed to compile and run the way you expect:
public class MyRunnable implements Runnable {
volatile boolean condition = false;
public void run() {
while (true) {
if (condition) {
System.out.println("second");
break;
}
}
}
public static void main(String args[]) {
final MyRunnable r = new MyRunnable();
new Thread(r).start();
System.out.println("first\n");
r.condition = true;
}
}
For comparison, a program with a CountDownLatch:
public class MyRunnable implements Runnable {
final CountDownLatch latch = new CountDownLatch(1);
public void run() {
try { latch.await(); } catch (InterruptedException e) {}
System.out.println("second");
}
public static void main(String args[]) {
final MyRunnable r = new MyRunnable();
new Thread(r).start();
System.out.println("first\n");
r.latch.countDown();
}
}
To truly notice the difference, add a Thread.sleep(20000) after println("first") and hear the difference in the sound of your computer's fan working hard to dissipate the energy the first program is wasting.
This seems like a place for java's wait notify construct.
public class MyRunnable implements Runnable {
public run() {
synchronized(this) {
try {
wait();
} catch (InterruptedException e) {
}
}
System.out.println("second");
}
public static void main(String args[]) {
Runnable r = new MyRunnable();
Thread t = new Thread(r);
t.start();
System.out.println("first\n");
synchronized (r) {
r.notify();
}
}
}
Don't do it that way. Instead, you can use Object's built in notify() and wait() methods like so:
public class MyRunnable implements Runnable {
private final Object condition;
public MyRunnable(Object condition) {
this.condition = condition;
}
public void run() {
condition.wait();
System.out.println("second");
}
public void go(String args[]) {
Object condition = new Object();
(new Thread(new MyRunnable(condition))).start();
System.out.println("first\n");
// set conndition to true
condition.notify();
}
}
If you want fancier notification schemes, you can also look in java.util.concurrent for more powerful ways of letting threads wait on more interesting conditions. All of these will be much more CPU-efficient than just spinning until a condition is true, and they're less likely to introduce concurrency bugs due to subtleties in Java's memory model.