java访问不同线程中的对象

时间:2012-01-24 05:45:07

标签: java multithreading concurrency synchronization

我搜索了很多但却无法找到特定的解决方案。在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.i我在每个线程的构造函数中传递mylist但是如何在对mylist执行添加和删除后返回一个对象? / p>

在我想到“如果我在线程的构造函数中传递mylist它将mylist的地址传递给线程并且线程执行对它的操作更改引用mylist对象”但它不是那样的更改没有被反射到mylist对象。任何人都可以详细说明这个吗?

实现这一目标的最佳方法是什么?

要求就是如果一个线程最后插入一个元素另一个线程应该能够删除其他索引的一些元素,同时说第二个。

修改

我做了如下: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();
    }
}

有没有其他方法可以这样做?

2 个答案:

答案 0 :(得分:8)

使用同步列表,这将是线程安全的

使用Collection.synchronizedList(yourPlainList)

答案 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关键字。