How to use java multi-threading properly? - java

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

Related

multithreading with loops inside the run() method

I have the following code to test multithreading. Inside the run() method, I have a loop. I instantiate my Runnable class and pass the object thus created to two different threads. My question is- How does the JVM deal with loop indexes ? Since a single Runnable object is passed to two different threads, won't it create confusion with loop indexes ?
public class ThreadTest1 implements Runnable{
public static void main(String[] args) {
ThreadTest1 tt = new ThreadTest1();
Thread t1 = new Thread(tt);
Thread t2 = new Thread(tt);
t1.start();
t2.start();
}
private synchronized void b() {
try {
for(int ii = 0; ii < 2; ii++) {
Thread.sleep(1000);
System.out.println("inside method 'b': " + this.toString() + " " + Thread.currentThread());
}
}
catch (InterruptedException e) {e.printStackTrace();}
}
#Override
public void run() {
this.b();
}
}

Main not waiting for threads even after using Thread.join() in Java

join() is supposed to make main function wait until all the threads complete execution, but main is printing completed before Thread-1 and Thread-2 completes execution.
I am unable to find error in the code. where's the mistake?
class ThreadDemo extends Thread {
private Thread t;
private String threadName;
ThreadDemo(String name) {
threadName = name;
}
public void run() {
System.out.println("Thread " + threadName + " exiting.");
}
public void start() {
if (t == null) {
t = new Thread (this, threadName);
t.start();
}
}
}
public class Problem2 {
public static void main(String[] args) {
ThreadDemo T1 = new ThreadDemo("Thread-1");
ThreadDemo T2 = new ThreadDemo("Thread-2");
T1.start();
T2.start();
try {
T1.join();
T2.join();
} catch (InterruptedException e) {
System.out.println("ERROR!");
}
System.out.println("completed");
}
}
Output
completed
Thread Thread-2 exiting.
Thread Thread-1 exiting.
You're joining on the ThreadDemo instances. But you're not running these instances as threads. Your overridden start method creates and starts another Thread.
Your code is extremely convoluted. You use both inheritance and delegation, and you override methods and break their contract: start() is supposed to start this as a thread, not create and start another thread.
Here's what it should look like:
class ThreadDemo implements Runnable {
private String threadName;
ThreadDemo(String name) {
this.threadName = name;
}
#Override
public void run() {
System.out.println("Thread " + threadName + " exiting.");
}
}
public class Problem2 {
public static void main(String[] args) {
ThreadDemo runnable1 = new ThreadDemo("Thread-1");
ThreadDemo runnable2 = new ThreadDemo("Thread-2");
Thread t1 = new Thread(runnable1);
Thread t2 = new Thread(runnable2);
t1.start();
t2.start();
try {
t1.join();
t2.join();
} catch (InterruptedException e) {
System.out.println("ERROR!");
}
System.out.println("completed");
}
}

Java Thread completion status

I have 2 threads t1 and t2, each one performs individual tasks.
I want to start thread t2 after 60% completion of task in thread t1.
Could anyone has any idea how can I achieve it ?
#Test
public void test() throws InterruptedException{
Thread t = new Thread( new Task1() );
t.start();
t.join(0);
//keep in mind that t2 can still be running at this point
System.out.println("done running task1.");
}
public static class Task1 implements Runnable{
public void run(){
//Smimulate some long running job. In your case you need to have your own logic of checking if t1 is 60% done.
//In this case we just wait 0.5 seconds for each 10% of work done
for (int i = 0; i < 10; i++){
try { Thread.sleep(500); }
catch (InterruptedException e) { throw new RuntimeException(e); }
int percentComplete = i*10;
System.out.println("Completed " + percentComplete + "%.");
if (percentComplete == 60){
new Thread( new Task2() ).start(); //this how to start t2 when we are 60% complete
}
}
}
}
public static class Task2 implements Runnable{
#Override
public void run() {
//simulate t2 task that will run for 5 seconds.
System.out.println("task2 started.");
try { Thread.sleep(5000); }
catch (InterruptedException e) { throw new RuntimeException(e); }
System.out.println("task2 is done.");
}
}
Can T1 know when it is 60% done? If so, then why not have it start T2 at that time?
Thread t2 = null;
class T2task implements Runnable {
...
}
class T1task implements Runnable {
#Override
public void run() {
while (isNotFinished(...)) {
if (isAtLeast60PercentDone(...) && t2 != null) {
t2 = new Thread(new T2task(...));
t2.start();
}
doSomeMoreWork(...);
}
}
}

How to run a thread after another?

Create three threads and the main thread. Execute each thread as simultaneous tasks. Display information when exiting each thread.
I can run two threads with above exercise, but it hard to three threads. This is my program.
package Thread;
import java.util.concurrent.atomic.AtomicBoolean;
public class Test {
static AtomicBoolean lock = new AtomicBoolean(false);
public static void main(String[] args) {
Thread t1 = new Thread(new Runnable() {
#Override
public void run() {
System.out.println("New Thread: "
+ Thread.currentThread().toString());
for (int i = 5; i > 0; i--) {
synchronized (lock) {
if (lock.get()) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("First: " + i);
if (i == 1) {
System.out.println("Second exiting.");
}
lock.set(true);
lock.notify();
}
}
}
});
Thread t2 = new Thread(new Runnable() {
#Override
public void run() {
System.out.println("New Thread: "
+ Thread.currentThread().toString());
for (int i = 5; i > 0; i--) {
synchronized (lock) {
if (!lock.get()) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Second: " + i);
if (i == 1) {
System.out.println("Second exiting.");
}
lock.set(false);
lock.notify();
}
}
}
});
t1.start();
t2.start();
try {
t1.join();
t2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Main thread exiting.");
}
}
And the result:
Can you give me some methods or tips to resolve this problem. Thank you for your reply!
It's unclear what you want three threads to do. With two threads you have
one waiting on the bool to be false and one waiting on it to be true, right?
With three threads you need three states to wait on. You also need to be
really careful to set it up in a way so the state transitions happens exactly
in the right order and a set amount of times.
Either try to write that program, and tell us what goes wrong, or if you want
design help it might be good to tell us more about what you want to achieve in
the end.
A suggestion if you have a real multithreaded problem that needs to be solved
is to look into something like queues. They are really nice high level abstractions
that makes working with threads much nicer.
More likely though, you have some artificial task that needs to be solved, and then
you need to speak a bit about the constraints you have.
Read tutorials here about Thread synchronization in Java.
public class sync extends Thread {
public void run() {
synchronized (this) {
for (int i = 5; i > 0; i--) {
System.out.print("Thread Name :" + Thread.currentThread().getName() + i+"\n");
}
}
}
}
class demo {
public static void main(String args[]) {
sync obj1 =new sync();
sync obj2 =new sync();
sync obj3 =new sync();
obj1.setName("First");
obj2.setName("Second");
obj3.setName("Third");
obj1.start();
obj2.start();
obj3.start();
}
}
O/p:
Thread Name :First5
Thread Name :First4
Thread Name :First3
Thread Name :First2
Thread Name :First1
Thread Name :Second5
Thread Name :Second4
Thread Name :Second3
Thread Name :Second2
Thread Name :Second1
Thread Name :Third5
Thread Name :Third4
Thread Name :Third3
Thread Name :Third2
Thread Name :Third1
HOPE THIS HELPS :)

Execute two threads which wait one for the other while main thread continues

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());
}
}
}
}
`

Categories

Resources