I am writing a multithreaded program in which i am getting exception java.lang.IllegalThreadStateException.
Any help would be welcomed
here is my stack trace
Exception in thread "main" java.lang.IllegalThreadStateException
at java.lang.Thread.start(Unknown Source)
at GeoMain.main(GeoMain.java:18)
here is my code for main class
public class TMain {
public static void main(String[] args) {
String Batchid="1,2,3";
String batch[]=StringUtils.split(Batchid,",");
MultiThread gt=new MultiThread();
for(int i=0;i<batch.length;i++){
gt.setBatch(batch[i]);
gt.start();
System.out.println("Thread started for "+batch[i]);
}
System.out.println("mainfinish");
}
}
and hereis my multi thread class
public class MultiThread extends Thread {
private static Queue<String> queue = new LinkedList<String>();
private static Boolean isInUse = false;
private void runcoder()
{
String batchid=null;
BatchIdCreator bid=null;
while(isInUse)
{
try {
Thread.sleep(60000);
} catch (InterruptedException e) {
System.out.println("exception");
e.printStackTrace();
}
}
isInUse=true;
synchronized(isInUse)
{
isInUse=true;
batchid=queue.poll();
System.out.println(batchid);
System.out.println(batchid);
bid=new BatchIdCreator(batchid);
// get a list from database
bid.getList();
// print on console
bid.printList();
isInUse=false;
}
}
#Override
public void run() {
runcoder();
}
public void setBatch(String batchid)
{
queue.add(batchid);
}
public static Boolean getIsInUse() {
return isInUse;
}
}
In this snippet:
MultiThread gt=new MultiThread();
for(int i=0;i<batch.length;i++){
gt.setBatch(batch[i]);
gt.start(); <--- Same thread object as in previous iteration
System.out.println("Thread started for "+batch[i]);
}
you're calling start() over and over again on the same thread. As described in the documentation, this is illegal:
It is never legal to start a thread more than once. In particular, a thread may not be restarted once it has completed execution.
You may want to move the new MultiThread() into the loop to avoid this:
----------.
for(int i=0;i<batch.length;i++){ |
|
MultiThread gt=new MultiThread(); <--'
gt.setBatch(batch[i]);
gt.start();
System.out.println("Thread started for "+batch[i]);
}
You cannot start the same thread twice. You you want to create several threads move the creation of thread instance into the loop:
for(int i=0;i<batch.length;i++){
MultiThread gt=new MultiThread();
gt.setBatch(batch[i]);
gt.start();
System.out.println("Thread started for "+batch[i]);
}
You are attempting to start the same (Multi)Thread instance multiple times. Create a new instance of Multithread inside the loop, so each thread gets its own instance.
Related
I don't know how to make for a thread to run until the task is finished.
So i have this class:
public class MainTest {
public static void main(String[] args){
ThreadRunnable t1 = new ThreadRunnable();
Thread t2 = new Thread(t1);
t2.start();
System.out.println(3);
//here the next code to run
}
}
And another that try for example to add data in database:
public class ThreadRunnable implements Runnable{
public void run(){
//code to make the thread waits until the insert is done
//code for inserting data in database
}
}
So, inside method run() i want something like:
- try to insert data in database
- if connection to database is down, wait 5 seconds and try again
- if connection is ok, then insert data, and return successful message that data is added
Is this possible, and if yes, how?
Thanks!
You don’t need to wait for a thread. Just do the retries in a loop in your Runnable:
public void run() {
try {
while (true) {
try {
// Do database operations here
// Succeeded
break;
} catch (SQLException e) {
// Failed; log exception and try again.
logger.log(Level.INFO, "Couldn't save data.", e);
}
// Wait before trying again.
Thread.sleep(5000);
}
} catch (InterruptedException e) {
logger.log(Level.INFO, "Interrupted; exiting.", e);
}
}
Note: An interrupt is an explicit request for a thread to stop what it’s doing and self-terminate. The InterruptedException should not be caught inside the loop, because you want the loop to terminate in the event of an interrupt.
On the other hand, you do want the loop to keep executing in the event of an SQLException, so it should be caught inside the loop.
You can do something like that :
1) Add a waitFor function in your ThreadRunnable
2) Add synchronization via un LOCK variable
The code :
public class ThreadRunnable implements Runnable{
private boolean ended=false;
private final Object LOCK=new Object();
public void run(){
// do my stuff...
...
//at the end, notify the thread waiting for : it will wake up
synchronized(LOCK)
{
ended=true;
LOCK.notifyAll();
}
}
/**
Waits until the task is done
*/
public void waitFor()
{
synchronized(LOCK)
{
while(!ended)
{
//sleeps until notifAll is called (see run())
wait();
}
}
}
}
(in this code, you have to add the try/catch for the InterruptedException)
In your main :
public class MainTest {
public static void main(String[] args){
ThreadRunnable t1 = new ThreadRunnable();
Thread t2 = new Thread(t1);
t2.start();
t1.waitFor();
System.out.println(3);
//here the next code to run
}
}
i'm wondering what the code would look like in order to have a program which creates a loop on start. This loop then creates several, thread objects all on their own threads so their all running at the same time, and they all run the same code. Is there a way to do this? as in for example we make 2 threads, they never stop looping and one is always prinintg "thread 1" and 1 is always printing "thread 2" at the same time. This is what i'm wondering. Thanks in advance!
class MyTask implements Runnable {
public static id = 0;
public MyTask(){
id++;
}
public void run(){
while(true){
System.out.print("Thread " + id);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Generator{
Public static void main(String[] args){
Runnable[] myTasks = new Runnable[2];
myTasks[0] = new MyTask();
myTasks[1] = new MyTask();
for(Runnable r: myTasks){
Thread t = new Thread(r);
t.start();
}
}
}
I didn't compile it. but this is how you are going to do.
When you run class Generator, two Threads will start, and they will print Thread 1. and thread 2 once every one second forever.
I am writing a code in java to print the output as follows
[spirit]
[of]
[wipro]
but i am facing a problem in setting the priorities of the threads and seeing each threads priorty and not getting output as expected.
class shobj
{
public synchronized void sharedMethod(String arg)
{
System.out.print("[");
System.out.print(arg);
try
{
Thread.sleep(1000);
}
catch(Exception e)
{
System.out.println("INTERRUPTED");
}
System.out.println("]");
}
}
class thread1 implements Runnable
{
String arg;
shobj obj1;
Thread t;
public thread1(shobj obj1,String arg)
{
this.obj1=obj1;
this.arg=arg;
t=new Thread(this);
t.start();
// System.out.println(t.currentThread());
}
public void run()
{
obj1.sharedMethod(arg);
}
}
class synchro
{
public static void main(String args[])
{
shobj ob = new shobj();
thread1 x1 = new thread1(ob,"spirit");
thread1 x2 = new thread1(ob,"of");
thread1 x3 = new thread1(ob,"wipro");
x3.t.setPriority(Thread.NORM_PRIORITY+3);
x2.t.setPriority(Thread.NORM_PRIORITY+2);
x1.t.setPriority(Thread.NORM_PRIORITY+1);
try
{
x1.t.join(); //System.out.println(x1.t.currentThread());
x2.t.join();//System.out.println(x2.t.currentThread());
x3.t.join();//System.out.println(x3.t.currentThread());
}
catch(Exception e)
{
System.out.println("Interruted Exception");
}
}
}
I am getting output as follows:
[spirit]
[wipro]
[of]
See How are Java Thread priorities translated to an OS thread priority? how the thread priority is mapped to the native OS. There is no guarantee that different thread priorities in java lead to different priority on OS level.
Priority is just a hint to the OS. If you have plenty of free CPU, all thread which want to run, can run.
This means all the threads in your case could run in any order which is what having multiple threads is designed to.
Is it possible to launch a new thread when the currently running thread exits?
The code i have written for a framework starts a thread and it locks(not a java concurrent lock) a file.
I need to process the same file,but i am not able to do so as the lock is held by the thread
launched by the framework. My requirement is to launch a new thread which processes the file
once the thread launched by the framework is completed
Thanks,
Senthil.
Use Thread.join() method
Refer Example
Refer documentation
Your basic code structure should be like his
public void run(){
//prepare
synchronized{
//Access File
}
//non-trivial statements
}
Here's an example that launches a second thread at the end of another thread:
public class TwoThreads {
public static void main(String[] args) {
class SecondThread implements Runnable {
#Override
public void run() {
System.out.println("Start of second thread");
try {
Thread.sleep(2000);
} catch (InterruptedException e) { }
System.out.println("End of second thread");
}
}
class FirstThread implements Runnable {
#Override
public void run() {
System.out.println("Start of first thread");
try {
Thread.sleep(1000);
} catch (InterruptedException e) { }
// Second thread gets launched here
new Thread(new SecondThread()).start();
System.out.println("End of first thread");
}
}
new Thread(new FirstThread()).start();
}
}
I am test a scenario to use volatile variable to stop one running thread from another.
I wonder why its not working. Where is the problem?
My code is:
public class StoppableTask extends Thread {
private volatile boolean pleaseStop;
public void run() {
System.out.println("Running..");
while (!pleaseStop) {
System.out.println("Working...");
}
}
public void tellMeToStop() {
pleaseStop = true;
}
}
public class Stopper extends Thread {
StoppableTask t ;
public Stopper(StoppableTask t){
this.t=t;
}
public void run(){
System.out.println("Ok..running too..");
try {
System.out.println("Waiting..");
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
t.tellMeToStop();
System.out.println("Done Waiting..");
}
public class QuickTest{
public static void main(String[] args) {
StoppableTask t = new StoppableTask();
Stopper s = new Stopper(t);
t.start();
s.start();
}
}
I suspect that your program is printing so much output to the terminal that it is blocking waiting for the output to be displayed. It looks like it is not stopping but really it will. You just need to wait... for a long time...
You should put a Thread.sleep(100); inside of of the while() spin loop in StoppableTask.run() to slow down that output. Another way to do it is to remove the System.out and just increment a counter or something.
I just tried it and your program finishes in 5 seconds as expected:
public void run() {
System.out.println("Running..");
while (!pleaseStop) {
// System.out.println("Working...");
}
System.out.println("Stopped task Done");
}
Your program is correct.
When working with threads i suggest you to use log4j instead of system.out.println.Configure the log4j to send output to a file.
You can search your string-pattern in a file. Its easy to analyse.