今天做了一个实验,想要用在线程之间共享static变量,以实现线程间的通信,结果因为Java的自动拆箱和装箱机制而失败了。下面为我的测试代码。
ShareData类(用于保存数据):
<pre class="java" name="code">public class ShareData {
private static Integer key = 1;
private static Integer value = 1;
public static final Integer defaultValue = 1000000;
public static String mark = "-----";
public static Integer getKey() {
return key;
}
public static void read() {
// TODO Auto-generated method stub
synchronized (key) {
synchronized (value) {
if (!key.equals(value)) {
mark = key + "---" + value;
}
}
}
}
public static void write() {
// TODO Auto-generated method stub
synchronized (key) {
synchronized (value) {
key++;
value++;
}
}
}
}
ReadThread类(用于读数据):
<pre class="java" name="code">public class ReadThread implements Runnable {
@Override
public void run() {
// TODO Auto-generated method stub
while (ShareData.getKey() < ShareData.defaultValue) {
ShareData.read();
}
System.out.println(ShareData.mark);
}
}
WriteThread类(用于写数据):
public class WriteThread implements Runnable {
@Override
public void run() {
// TODO Auto-generated method stub
while (ShareData.getKey() < ShareData.defaultValue) {
ShareData.write();
}
}
}
Test类:
public class Test {
public static void main(String[] args) {
Thread a = new Thread(new ReadThread());
Thread b = new Thread(new WriteThread());
a.start();
b.start();
}
}
从上面的代码可以发现,key和value的值都应该是同时增加的,那么打印出的mark值应该是“-----”,但是运行结果呢
这是为什么呢?为什么明明都加锁了,但是还是没有锁住呢!!
我纠结了很久,终于在师兄以及网友的帮助下,弄清楚了症结所在。那就是Java的自动拆装箱。
下面是我写的测试Java自动拆装箱的代码
Integer i = 300;
Integer j = i;
System.out.println(i==j);
j= i+1;
System.out.println(i==j);
运行结果如下:
在调试过程中,可以很清楚的看到i和j的id值变化了。也就是在Java拆装箱后都是产生了新的对象。OK,问题解决了。