首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java线程并发

Java线程并发
EN

Stack Overflow用户
提问于 2014-08-01 16:13:33
回答 4查看 112关注 0票数 2

在下面的示例中,有人能告诉我stampaVector()和stampaVector2()方法的区别吗?

代码语言:javascript
复制
public class ThreadConcurrence implements Runnable{

ArrayList<Integer> list=null;

public ThreadConcurrence(ArrayList<Integer> list){
    this.list = list;
}

public static void main(String[] args) {
    ArrayList<Integer> list = new ArrayList<Integer>();

    for(int i=0; i<5; i++){
        list.add(i);
    }

    //Threads shares same list object
    ThreadConcurrence tc1 = new ThreadConcurrence(list);
    ThreadConcurrence tc2 = new ThreadConcurrence(list);

    Thread t1 = new Thread(tc1);
    Thread t2 = new Thread(tc2);
    t1.start();
    t2.start();
}

@Override
public void run() {
    stampaVector();
    //stampaVector2();
}

public void stampaVector(){
    synchronized(this.list){
        for(Integer i:this.list){
            System.out.println("StampaVector: "+Thread.currentThread().getName()+" "+i);
        }
    }
}

public synchronized void stampaVector2(){
    for(Integer i:this.list){
        System.out.println("StampaVector2: "+Thread.currentThread().getName()+" "+i);
    }
}
}

执行stampaVector()的输出:

代码语言:javascript
复制
StampaVector: Thread-0 0
StampaVector: Thread-0 1
StampaVector: Thread-0 2
StampaVector: Thread-0 3
StampaVector: Thread-0 4
StampaVector: Thread-1 0
StampaVector: Thread-1 1
StampaVector: Thread-1 2
StampaVector: Thread-1 3
StampaVector: Thread-1 4

执行stampaVector2()的输出:

代码语言:javascript
复制
StampaVector2: Thread-0 0
StampaVector2: Thread-1 0
StampaVector2: Thread-1 1
StampaVector2: Thread-1 2
StampaVector2: Thread-0 1
StampaVector2: Thread-1 3
StampaVector2: Thread-1 4
StampaVector2: Thread-0 2
StampaVector2: Thread-0 3
StampaVector2: Thread-0 4

我希望stampaVector()的输出与stampaVector2()方法相同(只有一个线程同时访问list对象)。

谢谢

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2014-08-01 16:17:38

当您将synchronized放在方法上时,您正在this上进行同步。因为类有两个实例,所以每个实例都能够获得自身的锁,因此都同时运行(没有阻塞)。

synchronize this.list中,两个实例具有相同的list实例引用,因此它们都试图获取单个对象的锁,因此是相互排斥的。

票数 3
EN

Stack Overflow用户

发布于 2014-08-01 16:18:07

stampaVector的一部分正在您的列表中同步。多个线程无法在列表上执行同步代码。

stampaVector2在它内存在的ThreadConcurrance实例上是同步的。

其他线程只能在尚未同步的ThreadConcurrance实例上运行同步代码。

如果您希望在其他地方同步类,并确保其他地方的代码不与stampaVector2同时运行,请在stampaVector2中使用该方法。

对于使用这种方法的类,我不经常使用。我经常使用第一种方法。

票数 1
EN

Stack Overflow用户

发布于 2014-08-01 16:21:32

第一个方法stampaVector()在执行内部代码时同步list对象本身。这意味着执行这段代码的第一个线程(在您的例子中是Thread-0)获得list的监视器。因此,线程锁定该对象,在Thread-0释放监视器之前,不允许其他线程执行这段代码。之后,第二个线程Thread-1获取监视器并执行预期的方法。当您用相同的tc1引用初始化两个对象时,监视器会锁定完全相同的列表。

代码语言:javascript
复制
ThreadConcurrence tc1 = new ThreadConcurrence(list);
ThreadConcurrence tc2 = new ThreadConcurrence(list);

在第二种情况下,Thread-0获取ThreadConcurrence对象的监视器,因此,当执行stampaVector2()方法时,两个线程分别对tc1和tc2对象持有监视器,但不在列表本身上。因此,操作是不同步的。

例如,如果要初始化两个不同的列表,则结果是相同的:

代码语言:javascript
复制
ArrayList<Integer> list1 = new ArrayList<Integer>();
ArrayList<Integer> list2 = new ArrayList<Integer>();
ThreadConcurrence tc1 = new ThreadConcurrence(list1);
ThreadConcurrence tc2 = new ThreadConcurrence(list2);
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25084453

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档