Java доступ к объекту в разных потоках - PullRequest
5 голосов
/ 24 января 2012

Я много искал, но не смог найти конкретного решения. Есть также некоторые вопросы, касающиеся этого на stackoverflow, но я не могу найти удовлетворительный ответ, поэтому я спрашиваю его снова.

У меня есть класс, как следовать в Java. Я знаю, как использовать темы в 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
    }
}

Теперь я хочу сделать эти две операции одновременно. для этого я создал два класса потока, один из которых выполняет логику addString (), а другой выполняет deleteString () logic. Я передаю mylist в конструктор каждого потока, но как я могу вернуть объект после выполнения добавления и удаления в mylist?

Раньше я думал, что «если я передаю mylist в конструктор потока, он передает адрес mylist в поток, и поток выполняет над ним операции, которые изменяют ссылку на объект mylist». Но это не так, как изменения не отражаются на объекте mylist. Кто-нибудь может уточнить это?

Каков наилучший способ достичь этого?

требование таково, что если поток наконец-то вставляет элемент, другой поток должен иметь возможность удалить какой-либо элемент с другим индексом, например, 2-й одновременно.

EDIT

Я сделал это следующим образом: спасибо Энно Сиоджи

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();
    }
}

есть ли другой способ сделать это?

Ответы [ 2 ]

8 голосов
/ 24 января 2012

Использовать Синхронизированный список , Это будет потокобезопасно

Использовать Collection.synchronizedList(yourPlainList)

6 голосов
/ 24 января 2012

Потоки и экземпляр объекта - это разные понятия.Если вы хотите обмениваться данными между потоками, вам нужно получить доступ к одному экземпляру объекта из двух потоков.В этом случае вы должны сделать что-то вроде этого.

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
    }
}

, а затем

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();

Обратите внимание, как вы ссылаетесь на один и тот же экземпляр объекта (mine) из обоих потоков.Также обратите внимание, что я добавил ключевое слово synchronized, чтобы сделать MyClass поточно-ориентированным.Это заставляет все операции выполняться последовательно, а не «одновременно».Если вы хотите истинно одновременных операций над коллекцией, вам нужно будет использовать параллельные структуры данных, такие как Skip List, и избавиться от ключевого слова synchronized.

...