java线程学习(2)—对象的共享

编写安全的线程就是对共享数据的操作不出现问题,通过同步使来避免多个线程同一时刻方位共享数据,或者共享和发布对象,从而使能够安全地由多个线程同时访问。

可见性:

public class NoVisibility {
	private static boolean ready;
	private static int number;
	
	
	public static class ReaderThread extends Thread{
		public void run(){
			while(!ready)
				Thread.yield();
			System.out.println(number);
		}
	}
	
	public static void main(String[] args) {
		new ReaderThread().start();
		number = 42;
		ready = true;
	}
    
}

这段代码不推荐这么做,因为代码中没有使用足够的同步机制,无法保证主线程写入的值对于读线程来说是可见的。

实际上说就是主线程跟读线程共享变量number跟ready,主线程写入变量的值得时候,读线程很有可能看不到主线程写的值,程序的执行顺序可能不是我们想象中的那样,即程序可能会持续循环下去。(不过在我本机测试多少次,都是输出42,不知为何正常运行)

失效数据:

由于不同步的存在,访问的共享变量可能是更新后的最新值,也可能是以前的失效值。

当线程在没有同步的情况下读取变量,可能会得到一个失效值,至少这个值有之前的变量设置的值,而不是一个随机值,这种安全性被称为最低安全性。不过存在一个例外条件,就是非volatile类型的long或double变量,如果读写操作在不同的线程中执行,很有可能得到某个高32位或者低32位的随机值。

Volatile变量:

volatile boolean asleep;
    
	while(!asleep)
		countSomeSleep();

这段代码还是蛮有意思的  说某天失眠了,通过数羊来解决睡眠问题,然而入睡又是个多方面原因,这个可以看成多个线程在影响你是否入睡,asleep这个参数被多个线程控制,为了确保你现在是否真的睡着,asleep这个变量总是的到的最新值。

volatile提供一种比加锁机制稍弱的同步机制,确保这个变量一直被共享。加锁机制既可以确保可见性以及原子性,然而volatile智能确保可见性。volatile使用必须满足的条件:

对变量的写入操作不依赖变量的当前值,或者能确保只有单个线程更新变量的值。

该变量不会与其他状态变量一起纳入不变性条件中。

在访问变量时不需要加锁。


线程发布与逸出:

这部分内容现在感觉还晦涩难懂,以后再来说。


线程封闭:一种避免使用同步的方式就是不共享数据。如果数据都被封闭在各自的线程之中,就不需要同步。这种通过将数据封闭在线程中而避免使用同步的技术称为线程封闭。

1.Ad-hoc线程封闭

由于封闭技术的脆弱性,因此尽量少用它。

2.栈封闭



下边的内容读起来有困难,先跳过这一章。大哭大哭


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值