2012-01-24 5 views
4

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

У меня есть класс, как указано в 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() логику в run, а другой выполняет deleteString() logic.i передаёт mylist в конструкторе каждого потока, но как я могу вернуть объект после выполнения добавления и удаления в mylist?

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

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

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

EDIT

я сделал это следующим образом: Thanx к Энно 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(); 
    } 
} 

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

+0

Можете ли вы показать, как вы делаете темы и как вы пытаетесь вставить и удалить значение? – gprathour

+1

Ваш вопрос очень запутан. Вы описали класс 'myclass', но не один раз упоминаете об этом в своем вопросе. 'mylist' - это просто список с' add' и 'remove', для чего вам нужен' myclass'? Более важно увидеть код, который вы используете для создания потоков и кода, который использует 'add' и' delete'. –

+0

@AlexGitelman см. В редакторе –

ответ

7

Использования Синхронного Список, было бы поточно

Использование Collection.synchronizedList(yourPlainList)

+0

вы можете увидеть редактирование и сказать, как я могу реализовать это с помощью Collection.synchronizedList (yourPlainList)? –

+0

Я думаю, что он просил о параллельных операциях над данными, что невозможно для арраистов, потому что они поддерживаются обычными массивами. Он хочет, чтобы CopyOnWriteArrayList –

+1

. Ваш общий список должен быть синхронизирован только –

5

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

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 потокобезопасным. Это заставляет все операции выполняться последовательно, а не «одновременно». Если вам нужны настоящие одновременные операции с коллекцией, вам нужно будет использовать параллельные структуры данных, такие как Пропустить Список и избавиться от ключевого слова synchronized.

+0

для параллельной работы i используется частный Список mylist = Collections.synchronizedList (новый ArrayList ()); как указал джигар. Большое спасибо. –

Смежные вопросы