Skip to content

Commit c4dc1b3

Browse files
committed
java volatile关键字
1 parent 5042c9d commit c4dc1b3

File tree

4 files changed

+171
-1
lines changed

4 files changed

+171
-1
lines changed

_config.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,10 @@ weibo_username: #3115521wh
2222
zhihu_username: #gaohaoyang
2323
linkedIn_username: #gaohaoyang
2424
dribbble_username:
25-
2625
description_footer: 能立能达,不怨不尤
2726

27+
# img server
28+
img_server: http://www.codingted.com:9090
2829
# comments
2930
# two ways to comment, only choose one, and use your own short name
3031
# 两种评论插件,选一个就好了,使用自己的 short_name
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
---
2+
layout: post
3+
title: "java volatile 关键字"
4+
categories: java
5+
tags: core_java
6+
---
7+
8+
* content
9+
{:toc}
10+
11+
# volatile关键字两种特性
12+
13+
1. 线程可见性:当一个线程修改了被 volatile 修饰的变量后,无论是否加锁, 其它线程都可以立即看到最新的修改,而普通变量却做不到这点;
14+
2. 禁止指令重排序优化,普通的变量仅仅保证在该方法的执行过程中所有依赖 赋值结果的地方都能获取正确的结果,而不能保证变量赋值操作的顺序与程
15+
序代码的执行顺序一致。举个简单的例子说明下指令重排序优化问题:
16+
17+
```
18+
public class Singleton {
19+
private static Singleton instance; //避免指令重排声明成 volatile
20+
private Singleton (){}
21+
22+
public static Singleton getSingleton() {
23+
if (instance == null) {
24+
synchronized (Singleton.class) {
25+
if (instance == null) {
26+
instance = new Singleton(); //指令重排,导致instance为null判断出错
27+
}
28+
}
29+
}
30+
return instance;
31+
}
32+
33+
}
34+
```
35+
36+
> new 创建对象的过程:
37+
>>1. 给 singleton 分配内存
38+
>>2. 调用 Singleton 的构造函数来初始化成员变量,形成实例
39+
>>3. 将singleton对象指向分配的内存空间(执行完这步 singleton才是非 null 了)
40+
>
41+
> 因为JVM 的即时编译器中存在指令重排序的优化。也就是说上面的第2步和第3步的顺序是不能保证的,最终的执行顺序可能是 1-2-3 也可能是 1-3-2。如果是后者,则在 3 执行完毕、2 未执行之前,被线程二抢占了,这时 instance 已经是非 null 了(但却没有初始化),所以线程二会直接返回 instance,然后使用,然后顺理成章地报错。为避免指令重排需要將*instance*声明为volatile
42+
43+
# 内存中变量的操作
44+
45+
![内存模型]({{img_server}}/tools/img/java_volatile.jpg)
46+
47+
JAVA 内存模型定义了八种操作来完成主内存和工作内存的变量访问,具体
48+
如下:
49+
1. lock:主内存变量,把一个变量标识为某个线程独占的状态;
50+
2. unlock:主内存变量,把一个处于锁定状态变量释放出来,被释放后的变量
51+
才可以被其它线程锁定;
52+
3. read:主内存变量,把一个变量的值从主内存传输到线程的工作内存中,以
53+
便随后的 load 动作使用;
54+
4. load:工作内存变量,把 read 读取到的主内存中的变量值放入工作内存的
55+
变量拷贝中;
56+
5. use:工作内存变量,把工作内存中变量的值传递给 java 虚拟机执行引擎,
57+
每当虚拟机遇到一个需要使用到变量值的字节码指令时将会执行该操作;
58+
6. assign:工作内存变量,把从执行引擎接收到的变量的值赋值给工作变量,
59+
每当虚拟机遇到一个给变量赋值的字节码时将会执行该操作;
60+
7. store:工作内存变量,把工作内存中一个变量的值传送到主内存中,以便
61+
随后的 write 操作使用;
62+
8. write:主内存变量,把 store 操作从工作内存中得到的变量值放入主内存
63+
的变量中。

_posts/java/img/java_volatile.jpg

38.3 KB
Loading
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
---
2+
layout: post
3+
title: IDEA配置maven tomcat插件Debug/热部署
4+
categories: tools
5+
tags: idea
6+
---
7+
8+
* content
9+
{:toc}
10+
11+
# 配置maven tomcat插件
12+
13+
## 集成tomcatX-maven-plugin
14+
15+
```xml
16+
<plugin>
17+
<groupId>org.apache.tomcat.maven</groupId>
18+
<artifactId>tomcat7-maven-plugin</artifactId>
19+
<!-- or if you want to use tomcat 6.x -->
20+
<!--<artifactId>tomcat6-maven-plugin</artifactId>-->
21+
<version>2.2</version>
22+
<configuration>
23+
<path>/</path>
24+
</configuration>
25+
</plugin>
26+
```
27+
28+
现在只需要运行就可以运行项目了
29+
30+
```
31+
mvn clean tomcat7:run
32+
```
33+
> 但是这仅仅是运行项目,在这种情况下不能debug也没有热部署的功能,每次必须进行关闭 **mvn tomcat7:shutdown**
34+
35+
## Idea Debug配置
36+
37+
* 添加maven的Run/Debug项(Run->Edit Config)
38+
39+
![选择maven](http://www.codingted.com:9090/tool/img/idea_debug.jpg)
40+
41+
* 填写相应的命令
42+
43+
![填写运行命令](http://www.codingted.com:9090/tool/img/idea_debug_2.jpg)
44+
45+
> 这样只要进行debug启动就可以调试了但是,改完以后idea是不会自动部署的。
46+
47+
## Idea 热部署
48+
49+
> 这种方法是通过tomcat的管理后天进行热部署
50+
51+
### 相关的步骤如下
52+
53+
* 修改tomcat的tomcat-users.xml
54+
55+
```xml
56+
<role rolename="admin"/>
57+
<role rolename="admin-gui"/>
58+
<role rolename="manager"/>
59+
<role rolename="manager-script"/>
60+
<role rolename="manager-gui"/>
61+
<role rolename="manager-jmx"/>
62+
<role rolename="manager-status"/>
63+
<user username="admin" password="admin" roles="admin,manager,manager-gui,admin-gui,manager-script,manager-jmx,manager-status"/>
64+
```
65+
66+
* 修改的pom文件的配置
67+
68+
```xml
69+
<plugin>
70+
<groupId>org.apache.tomcat.maven</groupId>
71+
<artifactId>tomcat7-maven-plugin</artifactId>
72+
<!-- or if you want to use tomcat 6.x -->
73+
<!--<artifactId>tomcat6-maven-plugin</artifactId>-->
74+
<version>2.2</version>
75+
<configuration>
76+
<url>http://localhost:8080/manager/text</url>
77+
<server>tomcat</server>
78+
<username>admin</username>
79+
<password>admin</password>
80+
<uriEncoding>UTF-8</uriEncoding>
81+
<path>/</path>
82+
</configuration>
83+
</plugin>
84+
```
85+
86+
* 修改maven的setting.xml文件
87+
88+
编辑**~/.m2/setting.xml** 添加如下内容:
89+
90+
```xml
91+
<settings>
92+
<servers>
93+
<server>
94+
<id>tomcat</id><!-- 这里的id和pom文件定义的server一致 -->
95+
<username>admin</username>
96+
<password>admin</password>
97+
</server>
98+
</servers>
99+
</settings>
100+
```
101+
102+
> 现在可以通过命令行来启动tomcat(**注意:是在外部不是通过mvn tomcat7:run进行启动的,因为这种条件下启动的配置和通过tomcat命令启动是不同的**
103+
104+
现在通过**mvn tomcat7:deploy**进行部署就可以了
105+
106+
最后还是没有实现maven-tomcat插件既能debug又能热部署(又没闲钱使用JReble的服务,只能凑合着了),如果后续有好的方法在更新此文。

0 commit comments

Comments
 (0)