Reputation: 30648
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
?
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.
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
Reputation: 240870
Use Synchronized List , It would be thread safe
Use Collection.synchronizedList(yourPlainList)
Upvotes: 11
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