7

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?

informatik01
  • 16,038
  • 10
  • 74
  • 104
Hemant Metalia
  • 29,730
  • 18
  • 72
  • 91
  • Can you show how you are making threads and how you are trying to insert and delete values ? – gprathour Jan 24 '12 at 05:53
  • 1
    Your question is extremely confusing. You described class `myclass` but not once you mention it in your question. `mylist` is simply a list with `add` and `remove`, what do you need `myclass` for? It's more important to see code that you use to create threads and code that uses `add` and `delete`. – Alex Gitelman Jan 24 '12 at 05:55
  • In your edit, I think you can make addString() and deleteString() synchronized methods while still use an ordinary ArrayList for mylist. Correct me if I am wrong. – xiaolong Aug 16 '13 at 16:05

2 Answers2

11

Use Synchronized List , It would be thread safe

Use Collection.synchronizedList(yourPlainList)

jmj
  • 237,923
  • 42
  • 401
  • 438
  • can you see the edit and say how can i implement this using Collection.synchronizedList(yourPlainList)? – Hemant Metalia Jan 24 '12 at 06:15
  • I think he was asking for concurrent operations on the data, which is not feasible with arraylists, because they are backed by plain arrays. He wants a CopyOnWriteArrayList – guido Jan 24 '12 at 06:16
  • 1
    Your list that is shared needs to be synchronized just – jmj Jan 24 '12 at 06:24
  • @JigarJoshi private List mylist = Collections.synchronizedList(new ArrayList()); done. – Hemant Metalia Jan 24 '12 at 06:34
  • How about defining the plain list as 'private synchronized List mylist=new ArrayList()' will it work ? – Amit Mar 23 '12 at 06:38
  • 1
    @rahul that will not compile, `synchronized` is not a modifier – jmj Mar 23 '12 at 06:43
  • Thanks for reminding me about it, However I think a plain list with a set of synchronized methods can still do the task... What u say ? – Amit Mar 23 '12 at 07:26
  • yes but we need to force them not to access the list directly from any where else – jmj Mar 23 '12 at 07:29
9

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.

Enno Shioji
  • 26,542
  • 13
  • 70
  • 109
  • for concurrent operation i used private List mylist = Collections.synchronizedList(new ArrayList()); as jigar has specified. thanx alot. – Hemant Metalia Jan 24 '12 at 07:06