锁定老帖子 主题:java线程安全总结
该帖已经被评为精华帖
|
|
---|---|
作者 | 正文 |
发表时间:2011-06-13
546144153 写道
xyz317100759 写道
jameswxx 写道
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() { if (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) { if (eggs.size() > 0) { try { wait(); } catch (InterruptedException e) { } } eggs.add(egg);// 往盘子里放鸡蛋 notify();// 唤醒阻塞队列的某线程到就绪队列 System.out.println("放入鸡蛋"); } LZ这个太不靠谱了 判断条件居然用的是if
其实本应该用while的,只是这里给出的是只有两个线程的demo,就没写那么严谨了。 |
|
返回顶楼 | |
发表时间:2011-06-13
生活小丑 写道 楼主列出的这几个方面都是自己最近要学习的,有些也看了一段时间了,比如内存模型,恕我直言,楼主关于内存模型的内容是自己写的么?我貌似什么地方看过,当时看的时候就有点模糊,希望楼主能通俗解释一下,在此先谢过!
java的内存模型我就是自己写的阿,我觉得已经写得比较通俗易懂了。内存模型就是那些东西,建议你看看《java并发编程实践》 |
|
返回顶楼 | |
发表时间:2011-06-20
本不想多说话,那么多人纠结新帖隐藏贴
名利害死人,管别人投什么呢 虚拟的等级就是三个太阳也白扯,屁用不顶 受益颇多 |
|
返回顶楼 | |
发表时间:2011-06-21
最后修改:2011-06-21
总得来说不错。
但,没引入happen-before模型,对jdk1.5之后,对volatile,final等关键字的语义的解释,以及对并发有序性的理解,有些偏差。建议参考jsr133。 我猜这是大多数人投隐藏的原因。 |
|
返回顶楼 | |
发表时间:2011-07-06
最后修改:2011-07-06
内容删除, sorry
|
|
返回顶楼 | |
发表时间:2011-07-07
关注 楼主辛苦了。
|
|
返回顶楼 | |
发表时间:2011-07-08
很好的文章,对多线程描述的很到位。
|
|
返回顶楼 | |
发表时间:2011-07-14
谢谢分享,写的简单易懂。
|
|
返回顶楼 | |
发表时间:2011-07-15
之前对java线程的问题一直都很模糊,尤其是线程安全的同步问题,什么情况下该同步不该同步以及如何同步对哪些区块同步都比较模糊,看了楼主的文章,感觉明白了许多,非常感谢,希望楼主以后多发些这些文章,让我们多学习学习。O(∩_∩)O哈哈~
|
|
返回顶楼 | |
发表时间:2011-07-17
我艹,这个太给力了,不顶不行!
|
|
返回顶楼 | |