首页 > 编程语言 > 详细

java线程安全

时间:2014-06-11 10:27:42      阅读:320      评论:0      收藏:0      [点我收藏+]

可见性

1
Java内存模型(JMM)规定了jvm有主内存,主内存是多个线程共享的。当new一个对象的时候,也是被分配在主内存中,<br> 每个线程都有自己的工作内存,工作内存存储了主存的某些对象的副本,当然线程的工作内存大小是有限制的。

  (1) 从主存复制变量到当前工作内存 (read and load)
 (2) 执行代码,改变共享变量值 (use and assign)
 (3) 用工作内存数据刷新主存相关内容  (store and write)

有序性

bubuko.com,布布扣
线程在引用变量时不能直接从主内存中引用,如果线程工作内存中没有该变量,则会从主内存中拷贝一个副本到工作内存中,这个过程为read-load,完成后线程会引用该副本。当同一线程再度引用该字段时,有可能重新从主存中获取变量副本(read-load-use),也有可能直接引用原来的副本(use),也就是说 read,load,use顺序可以由JVM实现系统决定。
        线程不能直接为主存中中字段赋值,它会将值指定给工作内存中的变量副本(assign),完成后这个变量副本会同步到主存储区(store-write),至于何时同步过去,根据JVM实现系统决定.有该字段,则会从主内存中将该字段赋值到工作内存中,这个过程为read-load,完成后线程会引用该变量副本,当同一线程多次重复对字段赋值时
bubuko.com,布布扣

bubuko.com,布布扣

bubuko.com,布布扣
public class Account {
    private int balance;
    public Account(int balance) {
        this.balance = balance;
    }
    public int getBalance() {
        return balance;
    }
    public synchronized void add(int num) {
        balance = balance + num;
        System.out.println(Thread.currentThread().getName() + "-" + balance);
    }
    public synchronized void withdraw(int num) {
        balance = balance - num;
        System.out.println(Thread.currentThread().getName() + "-" + balance);
    }
    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 void run() {
            for (int i = 0; i < 200000; i++) {
                account.add(amount);
            }
        }
        
        public AddThread(Account account, int amount) {
            this.account = account;
            this.amount = 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);
            }
        }
    }
}
bubuko.com,布布扣

bubuko.com,布布扣bubuko.com,布布扣

只有在对象锁池中的线程才有机会获得对象锁.执行同步代码块.

如果需要获得对象锁.线程需要从等待池.-移动->锁池-进一步->获得对象锁.

 

释放对象的锁<以下情况会释放对象锁>

1 执行完同步代码块就会释放锁

2 执行同步代码块过程中,遇到异常而导致线程终止锁被释放

3 在执行同步代码块过程中,遇到wait().执行该方法的线程

释放对象的锁.把该县城放到该对象的等待池中.

 

 

 

java线程安全,布布扣,bubuko.com

java线程安全

原文:http://www.cnblogs.com/cici-new/p/3772870.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!