zoukankan      html  css  js  c++  java
  • 演示stop暴力停止线程导致数据不一致的问题,但是有些有趣的发现 (2017-07-03 21:25)

    如注释所言

    /**
     * Created by weiwei22 on 17/7/3.
     *
     * 这里主要是为了演示stop导致的数据不一致的问题。stop会暴力的结束线程并释放锁,所以有可能在恰好写了一半数据的时候,就被stop并释放了锁。
     * 读线程此时获得锁就有可能读取到不一致的数据。
     * 但是发现几个有意思的现象:
     * 1、如果M<N,那么所有的Thread1线程实例都没有机会执行就被干掉了,
     *    因为新创建的Thread1的实例t1在执行到(1)处时,休息N毫秒,几乎同时主线程执行到(2)处,休息M毫秒,如果M<N,就意味着主线程会先醒过来,
     *    然后先下手为强,干掉t1;
     * 2、如果M>=N,意味着t1有机会执行,或者不会执行。但是如果M>N,但是M<2N,则意味着t1只有执行一次的机会。因为t1执行完一轮后,立即进入2轮,但是第2轮
     *    休眠还没结束,主线程就醒了,然后干掉了t1;
     * 3、如果M>=2N,那么t1就有多次执行的机会,这取决于到底是几倍的关系;
     */
    
    public class ThreadMain8 {
        private static  User mU = new User();
    
        public static void main(String[] args) throws InterruptedException {
            Thread2 t2 = new Thread2("读取线程");
            t2.start();
    
            int index = 1;
            while (true) {
                Thread1 t1 = new Thread1("写入线程 " + index);
                index++;
                t1.start();
    
                //(2)处
                Thread.sleep(201);//M毫秒
    
                t1.stop();
            }
        }
    
        private static class Thread1 extends Thread {
            public Thread1(String name) {
                super(name);
            }
    
            @Override
            public void run() {
                while (true) {
                    synchronized (mU) {
    
                        mU.id = (int) (System.currentTimeMillis() / 1000); //(1)处
                        try {
                            Thread.sleep(100); //N毫秒
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        mU.name = mU.id;
    
                        SystemUtil.p(Thread.currentThread().getName() + "--写入 Name = " + mU.name);
                    }
                }
            }
        }
    
        private static class Thread2 extends Thread {
            public Thread2(String name) {
                super(name);
            }
    
            @Override
            public void run() {
    
                while (true) {
                    synchronized (mU) {
                        if (mU.name != mU.id) {
                            SystemUtil.p(Thread.currentThread().getName() + "--读取 Name = " + mU.name + ", id = " + mU.id);
                        }
                    }
                }
            }
        }
    
        private static class User{
            public int id = 0;
            public int name = 0;
        }
    }
  • 相关阅读:
    3、字节流输入输出实现文件的copy
    2、io的读出数据到文件中的内容(文件字节输出流)
    1、io的读取文件中的内容(文件字节输入流)
    10 linux中运行jar
    Linux 部署 iSCSI 客户端配置(Linux)
    Linux 部署 iSCSI 服务端
    Linux上使用iSCSI概述
    SSH实现免密登陆
    源码安装Python3
    Windows(受控主机)上配置
  • 原文地址:https://www.cnblogs.com/wlrhnh/p/7113139.html
Copyright © 2011-2022 走看看