简体   繁体   中英

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. 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! 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.

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.

The println has internal synchronization which causes the changes between the threads to be visible.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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