简体   繁体   English

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

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

There are two thread, A Thread let the list add ten times, B Thread will quit when the list.size() > 5.I think the result should be "B would quit after A add 5, maybe 6,7,7,8,9",but the result is B never quit. 有两个线程,A线程让列表添加十次,B线程将在list.size()> 5时退出。我认为结果应为“ B在A加5后退出,也许6,7,7, 8,9“,但结果是B永远不会退出。 and the other question is when i add a line there, it would be ok! 而另一个问题是,当我在此处添加一行时,就可以了! why? 为什么?

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

the result is B Thread never stop! 结果是B线程永不停止! this is my first question. 这是我的第一个问题。

the second is , when I add this line 第二个是,当我添加此行时

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

and it will be ok, Why?!! 没关系,为什么?! how they works! 他们如何工作!

Thread B is not guaranteed to see any changes from thread A because there is no synchronization between them. 线程B不能保证看到线程A的任何更改,因为它们之间没有同步。

Volatile won't do anything here as it only ensures the reference to the list is visible to both threads but not updates to its contents. Volatile在这里不会做任何事情,因为它仅确保对列表的引用对于两个线程都是可见的,而不会更新其内容。

The println has internal synchronization which causes the changes between the threads to be visible. println具有内部同步,该同步使线程之间的更改可见。

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

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