java-多线程深入(二)互斥性和可见性

来源:互联网 发布:淘宝卖家签约村淘 编辑:程序博客网 时间:2024/06/07 08:34

(一)互斥性

互斥性,即原子性。原子,指最小的物质,具体不可再分性。

CPU运算中,对多线程进行时间片分割执行,一个程序块执行时不可分割,即满足互斥性原子性。

java中保证互斥性的方法:

1.用sychronized锁住程序块,实行互斥

synchronized (lock) {      a++;}

2.用Atomic对变量操作实行互斥

public final static AtomicInteger TEST_INTEGER = new AtomicInteger(1);            public static void main(String []args) throws InterruptedException {          final Thread []threads = new Thread[20];           for(int i = 0 ; i < 20 ; i++) {               final int num = i;               threads[i] = new Thread() {                   public void run() {                     int now = TEST_INTEGER.incrementAndGet();                      System.out.println("我是线程:" + num + ",我得到值了,增加后的值为:" + now);                   }               };               threads[i].start();           }           for(Thread t : threads) {               t.join();           }           System.out.println("最终运行结果:" + TEST_INTEGER.get());      }  
TEST_INTEGER在多线程操作中,最终结果不会出现偏差。

JDK的文档中说:“设计原子类主要用作各种块,用于实现非阻塞数据结构和相关基础结构类。compareAndSet()方法不是锁定的常规替换方法。仅当对象的重要更新限于单个变量时才应用它”。


(二)可见性

cpu和内存速度相差过高,引入缓存(cache、寄存器等);一个线程由线程id、指令计数器PC、寄存器集合和堆栈构成,详见《程序员的自我修养》。

每个线程有自己的工作内存,修改进程主内存的值,都需要拷贝到工作内存修改后,再回写,其他线程可能出现,读取到未回写的脏数据这种情况。

/** * 多线程可见性测试 *  * @author peter_wang * @create-time 2015-1-12 下午3:56:29 */public class ThreadVisableDemo {    private static int a = 0;    static class GetNumThread        extends Thread {        @Override        public void run() {            System.out.println(a);//B1        }    }    static class ChangeNumThread        extends Thread {        @Override        public void run() {            a = 1;//A1,A2        }    }    /**     * @param args     */    public static void main(String[] args) {        GetNumThread getNumThread = new GetNumThread();        ChangeNumThread changeNumThread = new ChangeNumThread();        changeNumThread.start();//C1        getNumThread.start();//C2    }}
执行结果:输出0或者1


A1读取完数据进行操作,写入到线程A工作内存写缓存中,不一定实时刷新主内存中a的值,B1可能读取到旧数据。

java中保证可见性的方法:

1.用sychronized锁住程序块,实行互斥

static class GetNumThread        extends Thread {        @Override        public void run() {            synchronized (ThreadVisableDemo.class) {                System.out.println(a);// B1            }        }    }    static class ChangeNumThread        extends Thread {        @Override        public void run() {            synchronized (ThreadVisableDemo.class) {                a = 1;// A1,A2            }        }    }
2.使用volatile,保证变量可见性

private static volatile int a = 0;
3.使用Atomic对变量操作,实现可见性


0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 脸上两边长痘痘怎么办 我左脸比右脸大怎么办 左脸莫名肿了怎么办 牙疼得半边脸痛怎么办 手和脸突然发麻怎么办 右半边脸麻木了怎么办 左边脸突然肿了怎么办 左半边脸皮肤疼怎么办 脸内侧的肉肿了怎么办 上火引起的脸肿怎么办 脸肿里面有硬块怎么办 内分泌失调引起的肥胖怎么办 宝宝接种证丢了怎么办 不给补办接种证怎么办 儿童接种证丢了怎么办 疫苗接种本丢了怎么办 脊灰滴剂滴多了怎么办 鞋小了挤脚趾头怎么办 大母脚趾头疼是怎么办 小脚趾内侧长茧怎么办 小脚趾肿了很痛怎么办 穿袜子大脚趾痛怎么办 脚指头长水泡很痒怎么办 走路脚打起泡了怎么办 剪完脚趾甲肿了怎么办 大脚趾关节处疼怎么办 战士10穿不进去怎么办 脚上皮肤干燥起皮怎么办 脚趾头冻了很痒怎么办 大脚趾里面有脓怎么办 大脚趾肉肿了怎么办 大脚趾边上肿了怎么办 大母脚趾关节疼怎么办 大脚趾有点歪了怎么办 大脚趾扭伤肿了怎么办 大脚趾外翻怎么办 知乎 颈椎带着胳膊疼怎么办 胳膊酸困无力是怎么办 腰疼引起的腿麻怎么办 手臂到手指麻痛怎么办 拔完智齿特别疼怎么办