ankush yadav
ankush yadav

Reputation: 422

java arraylist returning same object by remove method in java 8

I have two thread which are sharing same list, fist thread adding new object in list, and second is performing the remove on same list. after some time of start both thread i got same object, why and how?

JAVA code: SubmitJob adding ThreadRuning class in to list.

public class SubmitJob extends Thread{

    public SubmitJob(List l){
        list = l;
    }
    List<ThreadRuning> list;
    private static int counter =0;
    public void run(){

        while(true){
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            ThreadRuning t = new ThreadRuning();
            t.setThreadname("Thread Name "+counter);
            t.setStarttime(new Date().getTime());
            list.add(t);
            //System.out.println("Submited"+t.getThreadname());
            counter++;
        }
    }
}

Second class is just removing object from list.

public class JobMoniter extends Thread {

    public JobMoniter(List l){
        list = l;
    }

    List<ThreadRuning> list;

    public void run() {
        while (true) {
            try {
                Thread.sleep(20);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            if (list.size()>0) {
                ThreadRuning t = list.remove(0);
                System.out.println(t.getState()+" name "+t.getThreadname());
                if(t!=null)t.start();
                //System.out.println("Startinf job"+t.getThreadname());
            }
        }
    }
}

When i get error java.lang.IllegalThreadStateException i was think it is related thread issue, after some study i found because of trying to start same thread twice. and getting this error so i pint the name of thread which i get from list than i know the remove method is returning same object twice once list size is increase, it is possible in java? rest of code is below.

public class ThreadUtile {

    public static void main(String[] args) {
        List<ThreadRuning> list = new ArrayList<ThreadRuning>();
        new SubmitJob(list).start();
        new JobMoniter(list).start();

    }

}

ThreadRuning class:

public class ThreadRuning extends Thread{

    private long starttime;
    private String threadname;

    public void run(){
        for(int i=0;i<10;i++){
            //System.out.println("Name of Thread "+threadname+ "Executing times"+i);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
// getter setter.


}

Note: i google but did not why? And if i remove the t.start() part from JobMoniter class and store the thread name in string and compare next time i found same name multiple time, but not each time.

For any further query write in comment.

Upvotes: 0

Views: 241

Answers (2)

Nicolas Filotto
Nicolas Filotto

Reputation: 45005

When you share an object, it needs to be thread safe to avoid unpredictable behavior that leads to bugs hard to fix. Here your share an ArrayList that is not thread safe, you should use a thread safe collection instead. If you really need a List, simply use the decorator Collections.synchronizedList(List) as next:

List<ThreadRuning> list = Collections.synchronizedList(new ArrayList<ThreadRuning>());
new SubmitJob(list).start();
new JobMoniter(list).start();

However a Queue seems to be much more appropriate, a ConcurrentLinkedQueue (which is a Queue implementation natively thread safe) could be a good choice here.

Upvotes: 1

Murat Karag&#246;z
Murat Karag&#246;z

Reputation: 37614

Beside the fact that you are trying to work in a concurrent environment on an ArrayList, you should really understand what references are in Java.

if (list.size()>0) {
    ThreadRuning t = list.remove(0);
    System.out.println(t.getState()+" name "+t.getThreadname());
    if(t!=null)t.start();
    //System.out.println("Startinf job"+t.getThreadname());
}

The method ArrayList.remove(int index) returns the removed object. It does not create a new instance of it. That's why you are getting IllegalThreadStateException when you try to start the Thread again.

Upvotes: 1

Related Questions