[转]java线程安全总结
http://www.iteye.com/wiki/jvm/2877-synchronized-volatile
一.java的内存模型JMM(解决可见性和有序性) 规定了jvm主内存
多线程不能相互传递数据,用共享变量
每个线程都有工作内存,其存储了主内存某些对象的副本.:
1)从主存复制对象到当前工作内存(read and load)
2)改变共享内存(use and assign) (其他线程可见)
3)工作内存数据刷新主存相关内容(store and write)
多次赋值时,可能只对工作内存副本操作,最后一次才同步到主存
导致不同步会出问题.
synchronized关键字保证了多个线程对于同步块是互斥的
而volatile关键字之解决多线程的内存可见性问题
二.java的线程同步机制
//不同步package com.test;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 {for (int i = 0; i < 100; i++) {Account account = new Account(1000);Thread a = new Thread(new AddThread(account, 20), "add");//创建threadThread b = new Thread(new WithdrawThread(account, 20), "withdraw");a.start();//启动b.start();a.join();b.join();System.out.println(i+":"+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 < 1000000; 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 < 1000000; i++) {account.withdraw(amount);}}}}
//线程安全public class Account {List<Object> eggs = new ArrayList<Object>();public synchronized Object getEgg() {if (eggs.size() == 0) {try {wait(); // 放弃锁} catch (InterruptedException e) {}}Object egg = eggs.get(0);//System.out.println("Get Egg,Eggs' size:" + eggs.size());System.out.println("============================");eggs.clear();// 清空盘子notify(); // 唤醒return egg;}public synchronized void putEgg(Object egg) {if (eggs.size() > 0) {try {wait();} catch (InterruptedException e) {}}eggs.add(egg);// 往盘子里放鸡蛋System.out.println("Put Egg,Eggs' Size:" + eggs.size());notify();// 唤醒阻塞队列的某线程到就绪队列}public static void main(String[] args) throws InterruptedException {Account account = new Account();Thread put = new Thread(new Put(account));Thread get = new Thread(new Get(account));put.start();get.start();// put.join();// get.join();}static class Put implements Runnable {Account account;Put(Account a) {this.account = a;}public void run() {for (int i = 0; i < 100000; i++) {Object egg = new Object();account.putEgg(egg);}}}static class Get implements Runnable {Account account;Get(Account a) {this.account = a;}public void run() {for (int i = 0; i < 1000000; i++) {account.getEgg();}}}}