1.volatile关键字有什么作用?
Java程序中,如果一个变量被volatile关键字修饰,那么这个变量就具有了有序性和可见性。
有序性:java语言中提供了synchronized和volatile两个关键字保证线程之间操作的有序性,也就是他可以使CPU指令有序。
可见性:当一个线程操作一个被volatile修饰的变量时,这个变量的修改对其他所有线程都是可见的,因为此时的操作不会将该变量读到当前线程的CPU缓存中进行操 作,而是直接操作内存
禁止重排序:volatile禁止了指令重排。比sychronized更轻量级的同步锁。在访问volatile 变量时不会执行加锁操作,因此也就不会使执行线程阻塞,因此volatile变量 是一种比sychronized关键字更轻量级的同步机制
Java语言提供了弱同步机制,即volatile变量,以确保变量的更新通知其他线程。当把变量声明为volatile类型后,编译器与运行时都会注意到这个变量是共享的,因此不会将该变量上的操作与其他内存操作一起重排序。volatile变量不会被缓存在寄存器或者对其他处理器不可见的地方,因此在读取volatile类型的变量时总会返回最新写入的值。
volatile适合这种场景:一个变量被多个线程共享,线程直接给这个变量赋值。
2编写Java程序模拟烧水泡茶最优工序。
package xinshi;
class Resource1 implements Runnable{
public void run(){
System.out.println("洗水壶"+"\n"+"烧开水");
try {
Thread.sleep(5000); //每运行一次,休眠一秒钟
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("烧完了");
}
}
class Resource2 implements Runnable{
public void run(){
for(int i=1;i<=3;i++){
if(i==1)
System.out.println("洗茶壶");
else {
if(i==2)
System.out.println("洗茶杯");
else
System.out.println("拿茶叶");
}
try {
Thread.sleep(1000); //每运行一次,休眠一秒钟
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Tea {
public static void main(String[] args) {
Resource1 r1=new Resource1();
Resource2 r2=new Resource2();
Thread t1=new Thread (r1);
Thread t2=new Thread (r2);
t1.setName("洗水壶-烧水");
t2.setName("洗茶壶-洗茶杯-拿茶叶");
t1.start();
t2.start();
try {
t1.join();
} catch (InterruptedException e) {
//等待t1完成
e.printStackTrace();
}
try {
t2.join();
} catch (InterruptedException e) {
// 等待t2完成
e.printStackTrace();
}
System.out.println("泡茶");
}
}
结果:
洗水壶
烧开水
洗茶壶
洗茶杯
拿茶叶
烧完了
泡茶