How to run a thread after another? - java

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 :)

Related

The ArrayList .add method does not work within a thread

I've tried to get a String from the request function and add it to the lastList ArrayList, but it will not be added normally.
In this case, how can I add?
As a global variable public ArrayList lastList = new ArrayList <> (); But it did not work.
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
Log.d(MainActivity.TAG, "Task runned.");
for (int i = 0; i < alarmList.size(); i++) {
final String str[] = alarmList.get(i).split("#!%~#");
for (int j = 0; j <= 8; j++) {
try {
final String output = AddActivity.request(str[1], str[2]);
handler.post(new Runnable() {
public void run() {
if (Integer.parseInt(str[3]) == Integer.parseInt(StringUtils.substringBetween(output, str[1] + " ", "화"))) {
lastList.add(output);
}
}
});
Log.d(MainActivity.TAG, "OK");
break;
} catch (Exception ex) {
Log.d(MainActivity.TAG, "Exception.");
}
}
}
}
});
thread.start();
try {
thread.join();
Log.d(MainActivity.TAG, "thread end.");
Log.d(MainActivity.TAG, "Size: " + lastList.size()); // Size: 0
}
I expect the output of Size: 1, but the actual output is Size: 0.
Not sure what is handler in your code, but seems like it makes http POST and then callback is executed in another thread after POST response. So, as I understand, you are making join on the thread thread, but you are updating the list in another thread which is executed in POST callback. Since http call normally takes much longer then executing several lines of code, you don't see your list updated. To be sure - try to put Tread.sleep(10000) after thread.join(); and check if the size is 1. Also, putting some debug log statements would be really helpful here, put some log line after this lastList.add(output), so you can see the sequence of execution.
Then you can, probably, fix it by making join on your callback thread as well.
Just to demonstrate the idea I came up with this test code:
static Thread innerThread;
static ArrayList lastList = new ArrayList<>();
public static void main(String[] args) {
System.out.println("Thread main: started.");
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
System.out.println("Thread thread: started.");
innerThread = new Thread(new Runnable() {
public void run() {
System.out.println("Thread innerThread: started.");
try {
System.out.println("Thread innerThread: sleeping for 1 second.");
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
lastList.add("test");
System.out.println("Thread innerThread: value added to the lastList");
System.out.println("Thread innerThread: ended.");
}
});
innerThread.start();
System.out.println("Thread thread: ended.");
}
});
thread.start();
try {
thread.join(); // to be sure that thread is finished - innerTread is initialized
innerThread.join(); // to be sure that innerTread is finished - lastList is updated
System.out.println("Thread main: lastList.size() = " + lastList.size()); // Size: 1
} catch (Exception e){
e.printStackTrace();
}
System.out.println("Thread main: ended.");
}
Output:
Thread main: started.
Thread thread: started.
Thread thread: ended.
Thread innerThread: started.
Thread innerThread: sleeping for 1 second.
Thread innerThread: value added to the lastList
Thread innerThread: ended.
Thread main: lastList.size() = 1
Thread main: ended.
Hope this will help!
The problem is that:
handler.post(new Runnable() {
makes your:
lastList.add(output);
execute after your logging:
Log.d(MainActivity.TAG, "Size: " + lastList.size()); // Size: 0
From your code its not clear why you need to use handler.post, its mostly used when you need to update UI widgets from worker thread.

How to use java multi-threading properly?

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

Java, threads deadlocked?

One of my friends showed me his code below, and I thought the two threads could be deadlocked, because they could deadlock while trying to acquire locks on the different variables: sb1 and sb2.
When I run the code, they don't seem to be deadlocked, as I was able to see the output:
A
B
second thread: AB
second thread: BA
Code below:
public static void main(String[] args) {
StringBuilder sb1 = new StringBuilder();
StringBuilder sb2 = new StringBuilder();
new Thread() {
public void run() {
synchronized (sb1) {
sb1.append("A");
synchronized (sb2) {
sb2.append("B");
System.out.println(sb1.toString());
System.out.println(sb2.toString());
}
}
}
}.start();
new Thread() {
public void run() {
synchronized (sb2) {
sb2.append("A");
synchronized (sb1) {
sb1.append("B");
System.out.println("second thread: " + sb1.toString());
System.out.println("second thread: " + sb2.toString());
}
}
}
}.start();
}
so could the two threads be deadlocked?
The code you posted has a potential deadlock. If it runs successfully, that just means you got lucky.
To demonstrate the potential deadlock, you can rig the timing to ensure that a deadlock occurs.
public static void main(String[] args) {
final StringBuilder sb1 = new StringBuilder();
final StringBuilder sb2 = new StringBuilder();
new Thread() {
public void run() {
synchronized (sb1) {
sb1.append("A");
System.out.println("Thread 1 has sync sb1");
try { Thread.sleep(700); }
catch (InterruptedException e) { e.printStackTrace(); return; }
System.out.println("Waiting for thread 1 to sync sb2");
synchronized (sb2) {
sb2.append("B");
System.out.println(sb1.toString());
System.out.println(sb2.toString());
}
}
}
}.start();
new Thread() {
public void run() {
try { Thread.sleep(500); }
catch (InterruptedException e) { e.printStackTrace(); return; }
synchronized (sb2) {
System.out.println("Thread 2 has sync sb2");
sb2.append("A");
System.out.println("Waiting for thread 2 to sync sb1");
synchronized (sb1) {
sb1.append("B");
System.out.println("second thread: " + sb1.toString());
System.out.println("second thread: " + sb2.toString());
}
}
}
}.start();
}
Now the first thread will definitely get the sync on sb1, and the second will get the sync on sb2, and then you will get a deadlock.
Output:
Thread 1 has sync sb1
Thread 2 has sync sb2
Waiting for thread 2 to sync sb1
Waiting for thread 1 to sync sb2
The fact that you are not getting a deadlock does not imply a deadlock cannot occur.
You are right in inferring that a deadlock might occur when two threads attempt to acquire monitors on two different resources in opposite orders.
Therefore, this code may produce a deadlock.
However, if any of the two threads manages to acquire both the monitors before the other, no deadlock will occur (which seems to be happening with your execution).
Here's how a deadlock might occur instead:
Thread one starts and acquires lock on sb1
Thread two starts and acquires lock on sb2
Thread one waits to acquire lock on sb2, which is owned by thread two
Thread two waits to acquire lock on sb1, which is owned by thread one
As no thread will release its lock and both wait on the other, you get a deadlock.
Note: as Khelwood advises, forcing the threads to sleep may prevent one of the threads from acquiring both locks first, hence producing the deadlock.
That code explains exactly a simple deadlock.
The easiest way to tell is basically because your Threads hold circular dependencies between each other.
This code alot of the times will result in a deadlock.
Yes, your program can end in a deadlock. Here a more dynamic example based on the answer of #khelwood. It adds some delay to the actual string appending and repeats it in a while loop. So you can see what is happening, sooner or later the program will end in a deadlock. To identify the deadlock situation ThreadMXBean.findDeadlockedThreads() is used.
package stack43323164;
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadMXBean;
import java.util.List;
import java.lang.management.ThreadInfo;
public class HowToDemonstrateDeadlock {
private static List<ThreadInfo> findDeadlocks() {
ThreadMXBean tmxb = ManagementFactory.getThreadMXBean();
long[] result = tmxb.findDeadlockedThreads();
if (result == null)
return java.util.Collections.emptyList();
return java.util.Arrays.asList(tmxb.getThreadInfo(result, 2));
}
public static void main(String[] args) {
final StringBuilder sb1 = new StringBuilder();
final StringBuilder sb2 = new StringBuilder();
long monitorDelay=1000L;
//You can play with the delay times to modify the results
long threadOneDelay=100L;
long threadTwoDelay=100L;
new Thread() {
public void run() {
try {
while (true) {
synchronized (sb1) {
sb1.append("A");
System.out.println("Thread 1 has sync sb1");
System.out.println("Waiting for thread 1 to sync sb2");
synchronized (sb2) {
sb2.append("B");
System.out.println(sb1.toString());
System.out.println(sb2.toString());
}
}
Thread.sleep(threadOneDelay);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
new Thread() {
public void run() {
try {
while (true) {
synchronized (sb2) {
System.out.println("Thread 2 has sync sb2");
sb2.append("A");
System.out.println("Waiting for thread 2 to sync sb1");
synchronized (sb1) {
sb1.append("B");
System.out.println("second thread: " + sb1.toString());
System.out.println("second thread: " + sb2.toString());
}
}
Thread.sleep(threadTwoDelay);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
new Thread() {
public void run() {
try {
while (true) {
List<ThreadInfo> deadlocks = findDeadlocks();
if (!deadlocks.isEmpty()) {
for (ThreadInfo i : deadlocks) {
System.out.println("Deadlock detected on thread " + i.getThreadId() + "\n" + i);
}
//Not a chance to solve the situation - boom
System.exit(1);
} else {
System.out.println("No deadlock so far.");
}
Thread.sleep(monitorDelay);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
}
}

java synchronize multiple thread issue

I just write some code to test the multiple threads how to synchronize,but I cannot get my expected result.The code can start 3 threads,but only one thread to process the shared resource.what is wrong with my code.
class ThreadDemo1{
public static void main (String[] args){
MultiThread tt = new MultiThread();
new Thread(tt).start();
new Thread(tt).start();
new Thread(tt).start();
}
}
class MultiThread implements Runnable {
int tickets = 100;
Object _lock = new Object();
public void run () {
System.out.println(Thread.currentThread().getName());
synchronized(_lock) {
while (true) {
if (tickets>0) {
try {
Thread.sleep(10);
} catch (Exception e) {}
System.out.println(Thread.currentThread().getName() + " is selling "+tickets--);
}
}
}
}
}
You are sleeping while holding the lock. There is no reason to multithread if you are going to do that.
public void run () {
System.out.println(Thread.currentThread().getName());
while(tickets > 0) {
synchronized(_lock) {
if (tickets > 0) {
System.out.println(Thread.currentThread().getName() + " is selling " + tickets--);
}
}
try {
Thread.sleep(10);
} catch (Exception e) {
}
}
}
I'm guessing the sleep was a placeholder for your processing. If possible, you should do the check and decrement inside the synchronized block, but your lengthy processing outside it.
In order for locks and multi-threading to do anything useful for you, you must make sure that your synchronized code takes as little time as possible, since that is the code that can be run by only one thread at a time.
In your code, the only thing that wasn't effectively single-threaded was your first System.println.
FYI, with that in mind, if you could have your print statements accurate but possibly out of order, it would be even better to have:
public void run () {
System.out.println(Thread.currentThread().getName());
while(tickets > 0) {
int oldTickets = 0;
synchronized(_lock) {
if (tickets > 0) {
oldTickets = tickets--;
}
}
if(oldTickets > 0) {
System.out.println(Thread.currentThread().getName() + " is selling " + oldTickets);
try {
Thread.sleep(10);
} catch (InterruptedException e) {
}
}
}
}
[1]First, there are several bad practice/mistakes in your posted code:
(1) It's better that the Lock Object to be singleton. You can use an static field object or the Class itself(Since there is only one Class in memory)
Object _lock = new Object();
private static final Object _lock = new Object();
(2) Put the while(true) {...} out of the synchronized block. In your code, if the 1st thread obtains the Lock, it will process ALL the tickets and will not stop.
Should make every thread try to obtain the Lock in each iteration of the loop.
(3) For the Thread.sleep(10), I guess you mean the thread is doing some heavy job. But it's not a good practice to put this kind of code in synchronized block(Or another name: critical region). Because there is only one thread can access the synchronized block at one time. The behavior of you code is like a single thread program, because other threads must wait until the currently running thread finishes its job.
Pls see below code:
public class ThreadDemo1 {
public static void main(String[] args) {
MultiThread tt = new MultiThread();
new Thread(tt).start();
new Thread(tt).start();
new Thread(tt).start();
}
}
public class MultiThread implements Runnable {
private static int tickets = 100;
private static final Object _lock = new Object();
public void run() {
System.out.println(Thread.currentThread().getName());
while (tickets > 0) {
try {
synchronized (_lock) {
if (tickets > 0) {
System.out.println(Thread.currentThread().getName() + " is selling " + tickets--);
}
}
Thread.sleep(10);
} catch (Exception e) {
}
}
}
}
[2]Second, if you just want to synchronize the threads in picking the tickets. Try to use Atomic* Classes instead of synchronized block, it’s No-lock and will bring you a better performance. Example:
import java.util.concurrent.atomic.AtomicInteger;
public class MultiThreadAtomic implements Runnable {
private static AtomicInteger tickets = new AtomicInteger(100);
public void run() {
System.out.println(Thread.currentThread().getName());
int ticketsRemaining = 0;
while ((ticketsRemaining = tickets.getAndDecrement()) > 0) {
System.out.println(Thread.currentThread().getName() + " is selling " + ticketsRemaining);
try {
Thread.sleep(10);
}
catch(InterruptedException ie) {}
}
}
}

safe way to stop a thread in java

public class thread extends Thread {
static volatile boolean done = false;// volatile keyword is used
#Override
public void run() {
while (!done) {
for (int i = 1; i < 10; i++) {
try {
thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(currentThread());
System.out.println("1st thread>> " + i);
}
}
}
public static void main(String[] args) throws InterruptedException {
Thread th = new Thread(new thread(),"mythread");
th.start();
for (int i = 1; i < 10; i++) {
thread.sleep(400);
System.out.println(currentThread());
System.out.println("2nd thread>> " + i);
if (i == 4) {
done = true;// safe way to stop a thread
break;
}
}
}
}
I am using volatile static variable here.Is it a safe way to stop a thread and also
when I print currentThread() method I get the output like Thread[mythread,5,main]
what does the 5 and main refer to??
It's a safe way to stop a thread, but there is no reason for the variable to be static: you want to stop one thread, not all threads of the same class.
Moreover, there is a more standard and less fragile way to stop a thread: interrupting it.
public void run() {
while (!Thread.currentThread().isInterrupted() {
...
}
}
...
th.interrupt();
This has the additional advantage that a thread which is sleeping or waiting, or blocked in an interruptible IO method will be woken up with an InterruptedException. When such an exception happens, it means that the thread should stop running, so you shouldn't swallow the exception as you did. Instead, you should return from the run method as fast as possible:
try {
thread.sleep(200);
}
catch (InterruptedException e) {
return;
}
Thread to toString, which is what is being called when you do System.out.println(currentThread()) prints out the thread name, priority, and thread group.
I'm assuming you are trying to interrupt the thread for something other then a normal completion, so why not just use Thread.interrupt() and Thread.isInterrupted()?

Categories

Resources