1. import java.util.ArrayList;
    2. import java.util.List;
    3. /**
    4. * volatile 关键字,使一个变量在多个线程间可见
    5. * mian,t1线程都用到一个变量,java默认是T1线程中保留一份副本,这样如果main线程修改了该变量,
    6. * t1线程未必知道
    7. * <p>
    8. * 使用volatile关键字,会让所有线程都会读到变量的修改值
    9. * <p>
    10. * 在下面的代码中,running是存在于堆内存的t对象中
    11. * 当线程t1开始运行的时候,会把running值从内存中读到t1线程的工作区,在运行过程中直接使用这个副本,
    12. * 并不会每次都去读取堆内存,这样,当主线程修改running的值之后,t1线程感知不到,所以不会停止运行
    13. * <p>
    14. * <p>
    15. *
    16. *
    17. */
    18. @Slf4j(topic = "enjoy")
    19. public class Demo {
    20. boolean running = true;
    21. List<String> list = new ArrayList<>();
    22. /**
    23. * t1线程
    24. */
    25. public void test() {
    26. boolean flag = running;
    27. while (running) {
    28. //加上任何一句话就会停止
    29. }
    30. }
    31. public static void main(String[] args) {
    32. Demo demo = new Demo();
    33. new Thread(demo::test, "t1").start();
    34. try {
    35. Thread.sleep(100);
    36. } catch (InterruptedException e) {
    37. e.printStackTrace();
    38. }
    39. demo.running = false;
    40. }
    41. }
    1. package com.shadow.demo10;
    2. import lombok.extern.slf4j.Slf4j;
    3. import java.util.ArrayList;
    4. import java.util.List;
    5. /**
    6. * 比如说第一个线程加到100了,还没往上加,另外一个线程来了,把100拿过来执行方法,
    7. * 然后第一个线程继续加到101,第二个线程也加到101,他两往回写都是101,线程不会管你加到哪儿了,
    8. * 虽然说加了2但是实际上只加了1.
    9. * volatile并不能保证多个线程共同修改running变量时所带来的不一致问题,
    10. * 也就是说volatile不能替代synchronized或者说volatile保证不了原子性
    11. */
    12. public class Demo {
    13. volatile int count = 0;
    14. public void test(){
    15. for (int i = 0; i < 10000; i++) {
    16. count ++;
    17. }
    18. }
    19. public static void main(String[] args) {
    20. Demo demo = new Demo();
    21. List<Thread> threads = new ArrayList();
    22. //new 10個线程
    23. for (int i = 0; i < 10; i++) {
    24. threads.add(new Thread(demo::test, "t-" + i));
    25. }
    26. //遍历这个10个线程 依次启动
    27. threads.forEach((o)->o.start());
    28. //等待10个线程执行完
    29. threads.forEach((o)->{
    30. try {
    31. o.join();
    32. } catch (Exception e) {
    33. e.printStackTrace();
    34. }
    35. });
    36. System.out.println(demo.count);
    37. }
    38. }