繁体   English   中英

当A Thread(list.add())和B Thread(list.size())工作时,此行如何工作?

[英]how this line works when A Thread(list.add()) and B Thread(list.size()) works?

有两个线程,A线程让列表添加十次,B线程将在list.size()> 5时退出。我认为结果应为“ B在A加5后退出,也许6,7,7, 8,9“,但结果是B永远不会退出。 而另一个问题是,当我在此处添加一行时,就可以了! 为什么?

package com.lock;

import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * Create by @author Henry on 2018/5/4
 */
public class NoWait {
    static volatile ArrayList list = new ArrayList();
    public static void main(String[] args) throws InterruptedException {

        ThreadA a = new ThreadA(list);
        a.setName("A");
        a.start();

        ThreadB b = new ThreadB(list);
        b.setName("B");
        b.start();

        Thread.sleep(10000);
        System.out.println("A is " + a.isAlive());
        System.out.println("B is " + b.isAlive());
    }
}

class ThreadA extends Thread{
    private ArrayList list;
    public ThreadA(ArrayList list){
        this.list = list;
    }

    @Override
    public void run(){
        try{
            for (int i = 0; i < 10; i++) {
                list.add(i);
                System.out.println("=====================================add "+(i+1));
                Thread.sleep(100);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("A finished");
    }
}

class ThreadB extends Thread{
    String s = "";
    private ArrayList list;
    public ThreadB(ArrayList list){
        this.list = list;
    }

    @Override
    public void run(){
        try{
            while(true){
                //s += list.size();
                //System.out.println(list.size());
                if(list.size() > 5){
                    System.out.println(">5 now, B gonne quit");
                    throw new InterruptedException();
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

结果是B线程永不停止! 这是我的第一个问题。

第二个是,当我添加此行时

//s += list.size();
//System.out.println(list.size());

没关系,为什么?! 他们如何工作!

线程B不能保证看到线程A的任何更改,因为它们之间没有同步。

Volatile在这里不会做任何事情,因为它仅确保对列表的引用对于两个线程都是可见的,而不会更新其内容。

println具有内部同步,该同步使线程之间的更改可见。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM