线程通信的原理

线程开始运行,拥有自己的的栈空间,就如同一个脚本一样,按照既定的代码一步一步地执行,直到终止。但是,每个运行中的线程,如果仅仅是孤立的运行,那么没有一点儿价值,或者说价值很少。如果多个线程能够相互配合完成工作,这将会带来巨大的价值。

volatile 和 synchronized 关键字

Java 支持多个线程同时访问一个对象或者对象的成员变量,由于每个线程可以拥有这个变量的拷贝(虽然对象以及成员变量分配的内存是在共享内存中的,但是每个执行的线程还是可以拥有一份拷贝,这样做的目的是加速程序的执行,这是现代多核处理器的一个显著特性),所以程序在执行过程中,一个线程看到的变量并不一定是最新的。

volatile

关键字volatile可以用来修饰字段(成员变量),就是告知程序任何对该变量的访问均需要从共享内存中获取,而对它的改变必须同步刷新回共享内存,它能保证所有线程对变量访问的可见性。
举个例子,定义一个表示程序是否运行的成员变量boolean on = true,那么另一个线程可能对它执行关闭动作(on = false),这里涉及多个线程对变量的访问,因此需要将其定义成为volatile boolean on = true,这样其他线程对它进行改变时,可以让所有线程感知到变化,因为所有对on变量的访问和修改都需要以共享内存为准。但是,过多的使用volatile 是不惜要的,因为它会降低程序执行的效率

synchronized

关键字synchronized可以修饰方法或者以同步块的形式来进行使用,它主要确保多个线程在同一时刻,只能有一个线程处于方法或者同步块中,它保证了线程对变量访问的可见性和排他性。
在如下代码清单中,使用了同步块和同步方法,通过使用javap工具查看生成的class文件信息来分析synchronized关键字的实现细节

public class synchronized{
   
	public static void main(String[] args){
   
	// 对synchronized class 对象进行加锁
		synchronized (Synchronized.class){
   
		}
		//静态同步方法,对Synchronized Class对象进行枷锁
		m();
	}
	public static synchronized void m(){
   
	};
}

在Synchronized.class 统计目录执行javap-v Synchronized.class 部分相关输出如下所示:

public static void main(java.lang.String[]);
	//方法修饰符,表示:public staticflags: ACC_PUBLIC, ACC_STATIC
	Code:
		stack=2, locals=1, args_size=1
		01dc    #1 //class com/murdock/books/multithread/book/Synchronized
		2: dup
		3: monitorenter //monitorenter:监视器进入,获取锁
		4: monitorenter //monitorexit:监视器退出,释放锁
		5: invokestatic  #16 //Method m:V
		8:

你可能感兴趣的:(线程框架,线程通信)