锁定老帖子 主题:java线程安全总结
该帖已经被评为精华帖
|
|
---|---|
作者 | 正文 |
发表时间:2010-11-09
最后修改:2011-11-03
java线程安全总结(二)请看http://www.iteye.com/topic/808550
最近想将java基础的一些东西都整理整理,写下来,这是对知识的总结,也是一种乐趣。已经拟好了提纲,大概分为这几个主题: java线程安全,java垃圾收集,java并发包详细介绍,java profile和jvm性能调优 。慢慢写吧。本人jameswxx原创文章,转载请注明出处,我费了很多心血,多谢了。关于java线 程安全,网上有很多资料,我只想从自己的角度总结对这方面的考虑,有时候写东西是很痛苦的,知道一些东西,但想用文字说清楚,却不是那么容易。我认为要认 识java线程安全,必须了解两个主要的点:java的内存模型,java的线程同步机制。特别是内存模型,java的线程同步机制很大程度上都是基于内 存模型而设定的。后面我还会写java并发包的文章,详细总结如何利用java并发包编写高效安全的多线程并发程序。暂时写得比较仓促,后面会慢慢补充完 善。
浅谈java内存模型
JVM规范定义了线程对主存的操作指
令:read,load,use,assign,store,write。当一个共享变量在多个线程的工作内存中都有副本时,如果一个线程修改了这个共享
变量,那么其他线程应该能够看到这个被修改后的值,这就是多线程的可见性问题。 for(int i=0;i<10;i++) a++; public class Account { private int balance; public Account(int balance) { this.balance = balance; } public int getBalance() { return balance; } public void add(int num) { balance = balance + num; } public void withdraw(int num) { balance = balance - num; } public static void main(String[] args) throws InterruptedException { Account account = new Account(1000); Thread a = new Thread(new AddThread(account, 20), "add"); Thread b = new Thread(new WithdrawThread(account, 20), "withdraw"); a.start(); b.start(); a.join(); b.join(); System.out.println(account.getBalance()); } static class AddThread implements Runnable { Account account; int amount; public AddThread(Account account, int amount) { this.account = account; this.amount = amount; } public void run() { for (int i = 0; i < 200000; i++) { account.add(amount); } } } static class WithdrawThread implements Runnable { Account account; int amount; public WithdrawThread(Account account, int amount) { this.account = account; this.amount = amount; } public void run() { for (int i = 0; i < 100000; i++) { account.withdraw(amount); } } } }
synchronized(锁){ 临界区代码 }
public synchronized void add(int num) { balance = balance + num; } public synchronized void withdraw(int num) { balance = balance - num; } synchronized(锁){ 临界区代码 } public class ThreadTest{ public void test(){ Object lock=new Object(); synchronized (lock){ //do something } } } Object lock=new Object();//声明了一个对象作为锁 synchronized (lock) { balance = balance - num; //这里放弃了同步锁,好不容易得到,又放弃了 lock.wait(); } import java.util.ArrayList; import java.util.List; public class Plate { List<Object> eggs = new ArrayList<Object>(); public synchronized Object getEgg() { while(eggs.size() == 0) { try { wait(); } catch (InterruptedException e) { } } Object egg = eggs.get(0); eggs.clear();// 清空盘子 notify();// 唤醒阻塞队列的某线程到就绪队列 System.out.println("拿到鸡蛋"); return egg; } public synchronized void putEgg(Object egg) { while(eggs.size() > 0) { try { wait(); } catch (InterruptedException e) { } } eggs.add(egg);// 往盘子里放鸡蛋 notify();// 唤醒阻塞队列的某线程到就绪队列 System.out.println("放入鸡蛋"); } static class AddThread extends Thread{ private Plate plate; private Object egg=new Object(); public AddThread(Plate plate){ this.plate=plate; } public void run(){ for(int i=0;i<5;i++){ plate.putEgg(egg); } } } static class GetThread extends Thread{ private Plate plate; public GetThread(Plate plate){ this.plate=plate; } public void run(){ for(int i=0;i<5;i++){ plate.getEgg(); } } } public static void main(String args[]){ try { Plate plate=new Plate(); Thread add=new Thread(new AddThread(plate)); Thread get=new Thread(new GetThread(plate)); add.start(); get.start(); add.join(); get.join(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("测试结束"); } } 执行结果: 放入鸡蛋 拿到鸡蛋 放入鸡蛋 拿到鸡蛋 放入鸡蛋 拿到鸡蛋 放入鸡蛋 拿到鸡蛋 放入鸡蛋 拿到鸡蛋 测试结束
public class VolatileTest{ public volatile int a; public void add(int count){ a=a+count; } }
public class VolatileTest{ public volatile int a; public void setA(int a){ this.a=a; } }
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2010-11-10
最后修改:2011-06-08
java线程安全总结(二)请看http://www.iteye.com/topic/808550
|
|
返回顶楼 | |
发表时间:2010-11-10
两个问题:
1. 文章排版不行,代码看起来累,弄个\[code\]包一下 2. 所谓深层背景不够深,一致性和可见性,希望能从字节码层面,操作系统MUTUX原语层面来介绍。系统级别如何控制和实现 |
|
返回顶楼 | |
发表时间:2010-11-10
不错,能学习到不少东西,楼主辛苦了
|
|
返回顶楼 | |
发表时间:2010-11-10
agapple 写道 两个问题:
1. 文章排版不行,代码看起来累,弄个\[code\]包一下 2. 所谓深层背景不够深,一致性和可见性,希望能从字节码层面,操作系统MUTUX原语层面来介绍。系统级别如何控制和实现 第一点你说的很好,我已经用code包了,多谢,原来还不知道这个功能,汗。 第二点,其实一开始我就说了,只是谈jvm的,如果从操作系统层面来谈,那是另外一回事。写得很仓促,欢迎多提意见,我会不断完善。 |
|
返回顶楼 | |
发表时间:2010-11-10
cuippan 写道 无私的楼主 辛苦了!
眼泪哗哗的,谢谢兄弟的鼓励。 |
|
返回顶楼 | |
发表时间:2010-11-10
介绍一下java专门处理多线程的工具包吧,这个我还不会使呢
|
|
返回顶楼 | |
发表时间:2010-11-10
西门吹牛 写道 介绍一下java专门处理多线程的工具包吧,这个我还不会使呢
会写的,java并发包的的东西很多,结合多线程来讲,会有很多内容,因此要花些时间。 |
|
返回顶楼 | |
发表时间:2010-11-10
volatile只能保证可见性,不能保证原子性
synchronized关键字,可以两者都保证 但相对来说性能堪忧 1.5并发包下java.util.concurrent.atomic.*的一些原子类是一个比较好的替换解决方案 |
|
返回顶楼 | |
发表时间:2010-11-10
看了很多有关进程的文章,这是感觉比较容易理解的一次。
|
|
返回顶楼 | |