This question already has answers here:
How do you kill a Thread in Java?
(17 answers)
Closed 2 years ago.
I'm working with threads in Java 8 and I'm using the next code:
Runnable runnable = () -> {
LOGGER.info(....);
someCode
};
Thread thread = new Thread(runnable);
thread.start();
My doubt is how can I stop or interrupt the thread or it will be stopped with itself?
Any ideas?
Thread will be automatically cleaned up after the public void run() method exits (implementation of which is your lambda expression), and there is no safe way you can explicitly tell the thread to stop.
However, you can simulate the stop instruction, if you'll either introduce a shared flag variable, or simply create your thread by extending the Thread class, instead of passing the Runnable to the Thread constructor. This way you can incorporate a flag field:
class MyThread extends Thread {
private boolean isAlive;
public MyThread() {
this.isAlive = true;
}
public synchronized void setAlive(boolean status) {
if (status == true) {
return;
}
this.isAlive = status;
System.out.println("Stopping " + Thread.currentThread().getName() + "thread..");
System.out.println(Thread.currentThread().getName() + " has been stopped.");
}
#Override
public void run() {
int i = 0;
while (isAlive) {
System.out.println(i + " invocation in the " + Thread.currentThread().getName() + "thread.");
++i;
try {
Thread.sleep(500);
} catch (InterruptedException e) {
}
}
}
}
public class MainClass {
public static void main(String[] args) throws Exception {
MyThread thread = new MyThread();
thread.start(); //instruction #1
Thread.sleep(2000);
System.out.println("In the main thread...");
Thread.sleep(2000);
System.out.println("In the main thread...");
thread.setAlive(false); //after this, you'll see, that the Thread running after instruction #1 doesn't exist anymore
Thread.sleep(2000);
System.out.println("In the main thread...");
Thread.sleep(2000);
System.out.println("In the main thread...");
}
}
Related
What will happen if we do entire Thread functionality in start method instead of run method?Below code runs in same way as it would have run if I added code in run method..
public class RunMethodTest extends AppCompatActivity {
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Abc abc=new Abc();
abc.start();
}
}
class Abc extends Thread
{
#Override
public synchronized void start() {
super.start();
for(int i=0;i<10;i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread" + " " + i);
}
}
}
Test it: have your code tell you which thread it is being called in by
Getting the current thread via Thread.currentThread()
And then getting the current thread's id and name via getId() and getName()
public class ThreadTest {
public static void main(String[] args) {
Thread currentThread = Thread.currentThread();
System.out.printf("Main, Which Thread: %s, %d%n",
currentThread.getName(),
currentThread.getId());
Abc abc = new Abc();
abc.start();
}
}
class Abc extends Thread {
#Override
public synchronized void start() {
super.start();
Thread currentThread = Thread.currentThread();
System.out.printf("Start, Which Thread: %s, %d%n",
currentThread.getName(),
currentThread.getId());
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread" + " " + i);
}
}
#Override
public void run() {
super.run();
Thread currentThread = Thread.currentThread();
System.out.printf("Run, Which Thread: %s, %d%n",
currentThread.getName(),
currentThread.getId());
}
}
For me this returns:
Main, Which Thread: main, 1
Start, Which Thread: main, 1
Run, Which Thread: Thread-0, 9
Thread 0
Thread 1
Thread 2
Thread 3
....
Which proves that your Abc's start method is (as expected) being called in the same thread as the calling code and not in a new thread, and that only code within the run() method is being called within a new thread. As has been noted above though, you almost never need to or want to extend Thread but rather implement Runnable or Callable.
I many examples in Internet there are almost all the same:
public class Test extends Thread {
public synchronized void run() {
for (int i = 0; i <= 10; i++) {
System.out.println("i::"+i);
}
}
public static void main(String[] args) {
Test obj = new Test();
Thread t1 = new Thread(obj);
Thread t2 = new Thread(obj);
Thread t3 = new Thread(obj);
t1.start();
t2.start();
t3.start();
}
}
So why would I call same task (in run() method) three times with different threads? E.g. if I want to upload a file, then why would I call it three times?
I assume if I need multithreading then:
thread t1 would do task1, e.g.:
- update database info
thread t2 would do task2, e.g.:
- upload file to server
thread t3 would do task3, e.g.:
- bring a message to an user
Is there an example that would to work like that described above.
You can create multiple threads the code given below where you only start thread and you don't need to call multiple times a same method. As you can see, once it started, all three child threads share the CPU. Notice the call to sleep(10000) in main( ). This causes the main thread to sleep for ten seconds and ensures that it will finish last.
// Create multiple threads.
class NewThread implements Runnable
{
String name;
} // name of thread Thread t;
NewThread(String threadname)
{
name = threadname;
}
t = new Thread(this, name);
System.out.println("New thread: " + t);
t.start(); // Start the thread
}
// This is the entry point for thread.
public void run()
{
try
{
for(int i = 5; i > 0; i--)
{
System.out.println(name + ": " + i);
Thread.sleep(1000);
}
} catch (InterruptedException e)
{
System.out.println(name + "Interrupted");
}
System.out.println(name + " exiting.");
}
}
class MultiThreadDemo
{
public static void main(String args[])
{
new NewThread("One"); // start threads
new NewThread("Two");
new NewThread("Three");
try
{
// wait for other threads to end
Thread.sleep(10000);
}
catch (InterruptedException e)
{
System.out.println("Main thread Interrupted");
}
System.out.println("Main thread exiting.");
}
}
Reference from The Complete Reference By Herbert Schildt
This question already has answers here:
Entering in block with an Intrinsic Lock
(2 answers)
Closed 8 years ago.
As I red somewhere, when we have synchronized methods, only one thread can use any of those method at the same time. The problem is that I have small peace of code that looks to break this rule, and I hope some of you knows why.
import java.util.Date;
public class SyncTest extends Thread {
private int state;
public static final int STATE_STOP = 10;
public static final int STATE_DO_TASK = 2;
public static final int STATE_FREE = 0;
public void run() {
try {
while(getThisState() != STATE_STOP) {
if(getThisState() == STATE_DO_TASK) {
Thread.sleep(2000);
setState(0);
}
}
}catch(Exception ex) {
ex.printStackTrace();
}
}
public synchronized void setState(int newState) {
this.state = newState;
this.notify();
}
public synchronized int getThisState() {
return this.state;
}
public synchronized void waitForComplete(int timeoutMilisec) {
try {
while( getThisState() != STATE_FREE) {
wait(timeoutMilisec);
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) {
SyncTest syncTest = new SyncTest();
syncTest.start();
syncTest.setState(STATE_DO_TASK);
System.out.println("Start operation: " + new Date());
syncTest.waitForComplete(30000);
syncTest.setState(STATE_STOP);
System.out.println("End operation: " + new Date());
}
}
What we have here is 'waitForComplete' method, that waits until state equals zero. While main thread waits, second thread is sleeping 5 seconds and then calls setState method. This changes 'state' variable to zero, and calls notify what unlocks waiting in main process. That seems to make sense, but the question is: How the hell it is possible that second thread executes 'setState' when on the same time main thread is inside 'waitForComplete' method. Both methods are synchronized, so it should be impossible to execute them simultaneously.
When you call wait() the thread releases its lock on the monitor, so other threads are free to enter the synchronized block.
How can I start two threads where thread1 executes first, thread2 starts when thread1 ends while the main method thread can continue its work without locking on the other two?
I have tried join() however it needs to be called from the thread which has to wait for the other, there's no way to do something like thread2.join(thread1);
If I call for a join inside main() I therefore effectively stop execution of the main thread and not only of thread2.
I therefore tried with ExecutorService but again same problem.
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class Test
{
public static void main(String args[]) throws InterruptedException
{
System.out.println(Thread.currentThread().getName() + " is Started");
class TestThread extends Thread
{
String name;
public TestThread(String name)
{
this.name = name;
}
#Override
public void run()
{
try
{
System.out.println(this + " is Started");
Thread.sleep(2000);
System.out.println(this + " is Completed");
}
catch (InterruptedException ex) { ex.printStackTrace(); }
}
#Override
public String toString() { return "Thread " + name; }
}
ExecutorService executor = Executors.newCachedThreadPool();
executor.execute(new TestThread("1"));
boolean finished = executor.awaitTermination(1, TimeUnit.HOURS);
if(finished)
{
//I should execute thread 2 only after thread 1 has finished
executor.execute(new TestThread("2"));
}
//I should arrive here while process 1 and 2 go on with their execution
System.out.println("Hello");
}
}
#EDIT: Why I need this:
I need this because Thread1 copies elements from a database table into another database, thread2 has to copy a linking table which references the table copied from thread1.
Consequently thread2 has to start populating its linking table only when thread1 has finished otherwise an integrity error is given by the database.
Now imagine I have several threads with different priorities due to complex linking tables and you have an idea.
The second Thread can be custom like this (takes as argument the previous thread):
public static void main(String[] a) {
Thread first = new Thread(new Runnable() {
#Override
public void run() {
}
});
Thread second = new MyThread(first);
first.start();
second.start();
//continue executing
}
public static class MyThread extends Thread {
private Thread predecessor;
public MyThread(Thread predecessor) {
this.predecessor = predecessor;
}
public void run() {
if (predecessor != null && predecessor.isAlive()) {
try {
predecessor.join();
} catch (InterruptedException e) {}
}
//do your stuff
}
}
You can use a CountDownLatch:
create it in the main thread, pass it on to both threads and call countdown on it in thread one when it exits and await it being counted down at the start of thread 2.
I am pretty sure you got something wrong because this must work and it does work:
new Thread() {
#Override
public void run() {
TestThread t1= new TestThread("1");
TestThread t2= new TestThread("2");
try {
t1.start();
t1.join();
t2.start();
t2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}.start();
The ouput is:
main is Started
Hello
Thread 1 is Started
Thread 1 is Completed
Thread 2 is Started
Thread 2 is Completed
Another option would be to extend the TestThread for the "Thread 1" to execute the work of "Thread 2" after it has been done with its own work. Something similar to this:
final TestThread t2= new TestThread("2");
TestThread t1= new TestThread("1") {
#Override
public void run() {
super.run(); //finish t1 work
t2.start(); // start t2 work
}
};
t1.start();
Why not just have thread1 be the one to start thread2?
// in main
new Thread(new Runnable() {
#Override public void run() {
// do thread1 work
new Thread(new Runnable() {
#Override public void run() { /* do thread2 work */ }
}).start();
}
}).start();
However, it's not at all clear why you would want to do this as opposed to just having thread1 do 100% of the background work.
You can use SingleThreadExecutor to run one task after another Java doc
So it will put your task one after another and they will execute in sequence without blocking main thread
Try this, This will work as expected. Two threads printing odd and even one after another and main exiting as soon as possible.
public class YoThreD {
static boolean isThread1 = false;
public static synchronized boolean isThread1() {
return isThread1 = !isThread1;
}
public static void main(String args[]) {
Runnable runnableObject = new Runnable() {
#Override
public void run() {
synchronized (this) {
for (int i = 1; i <= 100; i++) {
try {
if (Thread.currentThread().getName().equals("thread1")) {
if (isThread1()){
System.out.println(Thread.currentThread().getName() + " : " + i);
}else{
this.notify();
this.wait();
}
} else {
if (!isThread1()){
System.out.println(Thread.currentThread().getName() + " : " + i);
this.notify();
this.wait();
}
else{
}
}
} catch (Exception e) {
}
}
}
}
};
Thread thread1 = new Thread(runnableObject);
thread1.setName("thread1");
thread1.start();
Thread thread2 = new Thread(runnableObject);
thread2.setName("thread2");
thread2.start();
System.out.println(Thread.currentThread().getName() + "Main thread finished");
}
}
Silly question, but if thread 2 is supposed to execute when thread 1 is done... why not just start it from thread 1?
Or maybe just have thread 1 trigger an event and the main thread can just launch the new one in response to that.
I found this example, should work for you.
You can run two thread one after other by using several ways:
by using join() method. ex:
Thread t1=new Thread(new Runnable() {
#Override
public void run() {
for (int i = 0; i < 4; i++) {
System.out.println("A " + i);
}
}
});
Thread t2=new Thread(new Runnable() {
#Override
public void run() {
for (int i = 0; i < 4; i++) {
System.out.println("B " + i);
}
}
});
by using wait() and notify() methods: ex.
`
{
public class NotiffyAllExample {
int flag = 1;
public static void main(String[] args) {
NotiffyAllExample notiffyAllExample = new NotiffyAllExample();
A1 a = new A1(notiffyAllExample);
B1 b = new B1(notiffyAllExample);
C1 c = new C1(notiffyAllExample);
a.start();
b.start();
}
}
class A1 extends Thread {
NotiffyAllExample notiffyAllExample;
public A1(net.citigroup.mexico.pg.test.test.NotiffyAllExample notiffyAllExample) {
this.notiffyAllExample = notiffyAllExample;
}
#Override
public void run() {
try {
synchronized (notiffyAllExample) {
for (int i = 0; i < 4; i++) {
while (notiffyAllExample.flag != 1) {
notiffyAllExample.wait();
}
System.out.print("A ");
}
notiffyAllExample.flag = 2;
notiffyAllExample.notifyAll();
}
} catch (Exception e) {
System.out.println("Exception 1 :" + e.getMessage());
}
}
}
class B1 extends Thread {
NotiffyAllExample notiffyAllExample;
public B1(NotiffyAllExample notiffyAllExample) {
this.notiffyAllExample = notiffyAllExample;
}
#Override
public void run() {
try {
synchronized (notiffyAllExample) {
for (int i = 0; i < 4; i++) {
while (notiffyAllExample.flag != 2) {
notiffyAllExample.wait();
}
System.out.print("B ");
}
notiffyAllExample.flag = 1;
notiffyAllExample.notifyAll();
}
} catch (Exception e) {
System.out.println("Exception 2 :" + e.getMessage());
}
}
}
}
`
I have 4 threads witch are printing numbers from 15 to 0.I want to control executing of my threads for example I want first to thread D to finish and after him thread C and after him thread B and finally thread A. For now they are doing it all parallel.
How can I change that? any suggestions?
Here is my code:
// Suspending and resuming a thread for Java 2
class NewThread implements Runnable {
String name; // name of thread
Thread t;
boolean suspendFlag;
NewThread(String threadname) {
name = threadname;
t = new Thread(this, name);
System.out.println("New thread: " + t);
suspendFlag = false;
t.start(); // Start the thread
}
// This is the entry point for thread.
public void run() {
try {
for(int i = 15; i > 0; i--) {
System.out.println(name + ": " + i);
Thread.sleep(200);
synchronized(this) {
while(suspendFlag) {
wait();
}
}
}
} catch (InterruptedException e) {
System.out.println(name + " interrupted.");
}
System.out.println(name + " exiting.");
}
void mysuspend() {
suspendFlag = true;
}
synchronized void myresume() {
suspendFlag = false;
notify();
}
}
public class SuspendResume {
public static void main(String args[]) {
NewThread A = new NewThread("A");
NewThread B = new NewThread("B");
NewThread C = new NewThread("C");
NewThread D = new NewThread("D");
// try {
// System.out.println("****************************************************************");
// System.out.println(A.t.getState());
// System.out.println(B.t.getState());
// System.out.println(C.t.getState());
// System.out.println(D.t.getState());
//
// if(D.t.isAlive())
// {
// System.out.println("Bla bla bla");
// }
//
// Thread.sleep(1000);
// A.mysuspend();
// System.out.println("Suspending thread One");
// Thread.sleep(1000);
// A.myresume();
// System.out.println("Resuming thread One");
// B.mysuspend();
// System.out.println("Suspending thread Two");
// Thread.sleep(1000);
// B.myresume();
// System.out.println("Resuming thread Two");
//
//
//
// } catch (InterruptedException e) {
// System.out.println("Main thread Interrupted");
// }
// wait for threads to finish
try {
System.out.println("Waiting for threads to finish.");
A.t.join();
B.t.join();
C.t.join();
D.t.join();
} catch (InterruptedException e) {
System.out.println("Main thread Interrupted");
}
System.out.println("Main thread exiting.");
}
}
I think you should design structure of you service class first. I can suggest following:
public class Service {
private List<Service> dependencies;
// Starts service.
// It should wait until all dependencies started using awaitStart method and then start itself
public void start();
// Blocks current thread until service is started.
// If it is started returns immediately.
public void awaitStart();
// Stops service.
// Awaits until all dependencies are stopped using awaitStop.
public void stop();
// Blocks current thread until service is stopped.
// If it is already stops returns immediately
public void awaitStop();
// Actual code that has service specific code.
// This method may be invoked as last line in 'start' method.
public void run();
}
Next problem is to implement start and awaitStart (stop methods implemented similar). I recommend to use tools from java.util.concurrent for implementing awaitStart method. E.g. CountDownLatch. Each service has it's own latch that indicates that server is started. So code for awaitStart and start is following:
private CountDownLatch started = new CountDownLatch(1);
public void awaitStart() {
started.await();
}
public void start() {
for (Service service : dependencies) {
service.awaitStart();
}
System.out.println("Service " + name + " is started");
started.countDown();
run();
}