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?

3
  • Can you show how you are making threads and how you are trying to insert and delete values ? Commented Jan 24, 2012 at 5: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. Commented Jan 24, 2012 at 5: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. Commented Aug 16, 2013 at 16:05

2 Answers 2

11

Use Synchronized List , It would be thread safe

Use Collection.synchronizedList(yourPlainList)

Sign up to request clarification or add additional context in comments.

8 Comments

can you see the edit and say how can i implement this using Collection.synchronizedList(yourPlainList)?
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
Your list that is shared needs to be synchronized just
@JigarJoshi private List<String> mylist = Collections.synchronizedList(new ArrayList<String>()); done.
@rahul that will not compile, synchronized is not a modifier
|
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.

1 Comment

for concurrent operation i used private List<String> mylist = Collections.synchronizedList(new ArrayList<String>()); as jigar has specified. thanx alot.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.