Hemant Metalia
Hemant Metalia

Reputation: 30648

Java: access an object in different threads

I have searched a lot but not able to find particular solution. There are also some question regarding this on Stack Overflow but I am not able to find satisfactory answer so I am asking it again.

I have a class as follow in Java . I know how to use threads in java.

// Please do not consider syntax if there is printing mistake, as I am typing code just for showing the concept in my mind
    public class myclass{
    private List<String> mylist=new ArrayList<String>();

    public addString(String str) {
        // code to add string in list
    }

    public deleteString(String str) { // or passing an index to delete
        // code to delete string in list
    }
}

Now I want to do these two operations simultaneously. For that I have created two thread class one performs addString() logic in run and another perform deleteString() logic.

I am passing mylist in the constructor of each thread but how can I return an object after performing addition and deletion to mylist?


Before I was thinking that "If I am passing the `mylist` in constructor of thread it passes the address of the `mylist` to thread and thread performs operations on it that changes refer to `mylist` object". But it is not like that as the changes are not reflected to `mylist` object. Can any one elaborate on this?

What is the best way to achieve this?

The requirement is like that if a thread is inserting an element at last another thread should be able to delete some element at other index say 2nd simultaneously.


EDIT

I have done it as follow: thanx to Enno Shioji

public class myClass {
    
    private List<String> mylist = Collections.synchronizedList(new ArrayList<String>());
    public myClass() {
        mylist.add("abc");
        mylist.add("def");
        mylist.add("ghi");
        mylist.add("jkl");
    }
    public void addString(String str) {
        mylist.add(str);
    }

    public void displayValues() {
        for (int i = 0; i < mylist.size(); i++) {
            System.out.println("value is " + mylist.get(i) + "at " + i);
        }
    }

    public void deleteString(int i) {
        mylist.remove(i);
    }
}

class addThread {

    public static void main(String a[]) {
        final myClass mine = new myClass();
        Thread t1 = new Thread() {
            
            @Override
            public void run() {
                mine.displayValues();
                mine.addString("aaa");
                mine.displayValues();
            }
        };
        Thread t2 = new Thread() {
            
            public void run() {
                mine.displayValues();
                mine.deleteString(1);
                mine.displayValues();
            }
        };
        t1.start();
        t2.start();
    }
}

Is there any other way to do so?

Upvotes: 7

Views: 37718

Answers (2)

Jigar Joshi
Jigar Joshi

Reputation: 240870

Use Synchronized List , It would be thread safe

Use Collection.synchronizedList(yourPlainList)

Upvotes: 11

Enno Shioji
Enno Shioji

Reputation: 26882

Threads and object instance are different concepts. If you want to share data among threads, you need to access a single object instance from two threads. In this case, you should do something like this.

public class MyClass{
    private final List<String> mylist = new ArrayList<String>();

    public synchronized void addString(String str){
        //code to add string in list
    }

    public synchronized void deleteString(String str){
        //or passing an index to delete
        //code to delete string in list
    }
}

and then

final MyClass mine = new MyClass();
Thread t1 = new Thread(){
    public void run(){
        mine.addString("aaa");
    }
}();

Thread t2 = new Thread(){
    public void run(){
        mine.deleteString("bbb");
    }
}();

t1.start();
t2.start();

Note how you are referring to the same object instance (mine) from both threads. Also note that I added the synchronized keyword to make MyClass thread-safe. This forces all operations to be done sequentially rather than truly "simultaneously". If you want true simultaneous operations on the collection, you will need to use concurrent data structures like a Skip List and get rid of synchronized keyword.

Upvotes: 9

Related Questions