Java多线程(四)——volatile关键字

volatile关键字

当用volatile关键字声明变量的时候,就等于告诉虚拟机,这个变量极有可能被某些程序或者线程修改,为了保证比那辆被修改后应用程序范围内的所有线程可以看到这个改动,虚拟机必须采用一些方法保证这个变量的可见性。

volatile与死循环

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class PrintString {
private boolean isContinue = true;

public boolean isContinue() {
return isContinue;
}

public void setContinue(boolean aContinue) {
this.isContinue = aContinue;
}

public void printStringFunc(){
try {
while (isContinue){
System.out.println("run printStringFunc threadName=" + Thread.currentThread().getName());
Thread.sleep(1000);
}
}catch (InterruptedException e){
e.printStackTrace();
}
}

public static void main(String[] args){
PrintString printString = new PrintString();
printString.printStringFunc();
System.out.println("stop printStringFunc stopThread=" + Thread.currentThread().getName());
printString.setContinue(false);
}
}
1
2
3
4
5
6
7
8
9
run printStringFunc threadName=main
run printStringFunc threadName=main
run printStringFunc threadName=main
run printStringFunc threadName=main
run printStringFunc threadName=main
run printStringFunc threadName=main
run printStringFunc threadName=main
run printStringFunc threadName=main
...

上面的代码执行后会一直运行无法停下来,下面来看看解决方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
public class PringStringThread {

private boolean isContinue = true;

public boolean isContinue() {
return isContinue;
}

public void setContinue(boolean aContinue) {
this.isContinue = aContinue;
}

public void printStringFunc(){
try {
while (isContinue){
System.out.println("run printStringFunc threadName=" + Thread.currentThread().getName());
Thread.sleep(1000);
}
}catch (InterruptedException e){
e.printStackTrace();
}
}


}

public static void main(String[] args){

PringStringThread pringStringThread = new PringStringThread();
new Thread(() -> pringStringThread.printStringFunc()).start();
try {
Thread.sleep(2000);
}catch (InterruptedException e){
e.printStackTrace();
}
pringStringThread.setContinue(false);

}
1
2
3
4
run printStringFunc threadName=Thread-0
run printStringFunc threadName=Thread-0

Process finished with exit code 0

可以发现线程退出循环了。

volatile关键字与synchronized比较

  1. volatile关键字是线程同步的轻量级实现,所以volatile性能肯定比synchronized关键字要好。但是volatile关键字只能用于变量而synchronized关键字可以修饰方法以及代码块。synchronized关键字在jdk6之后进行了主要包括为了减少获得锁和释放锁带来的性能消耗而引入的偏向锁和轻量级锁以及其它各种优化之后执行效率有了显著提升,实际开发中使用synchronized关键字还是更多一些。
  2. 多线程访问volatile关键字不会发生阻塞,而synchronized关键字可能会发生阻塞。
  3. volatile关键字能保证数据的可见性,但不能保证数据的原子性。synchronized关键字两者都能保证。
  4. volatile关键字用于解决变量在多个线程之间的可见性,而synchronized关键字解决的是多个线程之间访问资源的同步性。

本节代码Github


欢迎关注公众号:
公众号微信

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
显示 Gitment 评论