java并发多线程问题demo求解答

mingyunzhidian 2018-05-31 10:58:59
public class DemoSafe {

private Integer val = new Integer(0);

public Integer getVal() {
synchronized (val) {
return val;
}
}

public void setVal(Integer val) {
synchronized (this.val) {
this.val = val;
}
System.out.println(Thread.currentThread().getName()+"set val:"+val);
}

public void setValAuto() {
synchronized (val) {
++this.val;
}
System.out.println(Thread.currentThread().getName()+"set val:"+val);
}
public static void main(String[] args) {
// final List<Demo> ls = Collections.synchronizedList(new ArrayList<Demo>());
// ls.add(new Demo());
/**
* Demo连续打印结果,发现最终结果并不是1000,说明是非线程安全的
* DemoSafe 打印的结果在980-1000之间,也是线程不安全?
* DemoSafe2 打印结果是1000,为线程安全对象
* **/
// final Demo d = ls.get(0);

final List<DemoSafe2> ls = Collections.synchronizedList(new ArrayList<DemoSafe2>());
ls.add(new DemoSafe2());
final DemoSafe2 d = ls.get(0);

for (int i = 0; i < 1000; i++) {
new Thread() {
public void run() {
d.setValAuto();
System.out.println(this.getName()+"get val:"+d.getVal());;
};
}.start();

}
try {
Thread.sleep(1000);
System.out.println("\n"+d.getVal());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
为什么,这个打印的最终结果不是1000?
...全文
1395 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
hongming09 2018-06-20
  • 打赏
  • 举报
回复
++ Integer 拆箱 int ++ 装箱 integer 不是原来对象
verejava 2018-06-20
  • 打赏
  • 举报
回复
​并发编程 之 线程 售票排队例子 http://www.verejava.com/?id=17236617240060
艾伦蓝 2018-06-20
  • 打赏
  • 举报
回复
public void setValue(int value) { synchronized (DemoSafe2.class) { this.value = value; } System.out.println(Thread.currentThread().getName() + "setValue:" + value); } public void setValueAuto() { synchronized (DemoSafe2.class) { ++this.value; } System.out.println(Thread.currentThread().getName() + "setValueAuto:" + value); }
  • 打赏
  • 举报
回复
没事测了测好像在循环是java 虚拟机优化,才会改变Integer 索引
  • 打赏
  • 举报
回复
最主要就是++this.val; 改变了锁对象,所以val就多个线程访问了。在测试时,发现个更有意思现象,
Integer one = new Integer()  ;  one ++   
one =  one ++ 
在单线程不一样,一个改变Integer 对象引用,一个不改变。很有趣,应该是虚拟机优化问题,在多线程下改变Integer 引用
good_reader 2018-06-14
  • 打赏
  • 举报
回复
for (int i = 0; i < 1000; i++) { new Thread() { public void run() { synchronized (d) { d.setValAuto(); } } }.start(); } 帮你改了下,写的真心乱

67,513

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧