zoukankan      html  css  js  c++  java
  • 线程的同步(Java内存模型)

    线程的同步

    保证多线程安全访问竞争资源的一种手段,避免多个线程同时修改一个资源,导致资源的不正确性。

    相关概念

    • 什么是竞争资源
    • 什么时候需要同步
    • 要怎样进行同步
    1. 将竞争资源标为private
    2. 将涉及到静态资源的方法或块用synchrized关键字修饰

    同步方法

    模拟银行转账功能

    package cn.domin.threadr.sync;
    public class Thransfer {
    		User u = new User();
    		u.setBalance(10000);
    		u.setCode(0x08);
    		
    		ATMThread a1 = new ATMThread("ATM1", u, 1000);
    		ATMThread a2 = new ATMThread("ATM2", u, 5000);
    		ATMThread a3 = new ATMThread("ATM3", u, 3000);
    		a1.start();
    		a2.start();
    		a3.start();
    	}
    }
    class ATMThread extends Thread{
    	private User u;
    	private int y;
    	public ATMThread(String name,User u,int y) {
    		super(name);
    		this.u = u;
    		this.y = y;
    	}
    	
    	public void oper(int y) {
    		int m = u.oper(y);
    		System.out.println(Thread.currentThread().getName()+"操作"+y+"元,账户余额"+m+"元");
    	}
    	
    	public void run() {
    		oper(y);
    	}
    	
    }
    
    class User{
    	private int code;
    	private int balance;
    	
    	public synchronized int oper(int y) {
    		try {
    			Thread.sleep(2000);
    		} catch (InterruptedException e) {
    			e.printStackTrace();
    		}
    		balance += y;
    		return balance;
    	}
    
    	public int getCode() {
    		return code;
    	}
    
    	public void setCode(int code) {
    		this.code = code;
    	}
    
    	public int getBalance() {
    		return balance;
    	}
    
    	public void setBalance(int balance) {
    		this.balance = balance;
    	}
    }
    

    volitile关键字

    • 修饰的变量在同一时间只能由一个线程进行操作
    • 需要注意的是,当变量的值和自身上一个值无关时,所做的操作才是原子级别的
    • 原子操作,是指不会被线程调度打断的操作,该线程
    • volatile属性操作并不能保证操作的原子性,可使用synchronized关键字、锁机制、同步类来保证操作的原子性。
    public class Thransfer {
    	
    	private volatile int it;
    	
    	public static void main(String[] args) {
    		User u = new User();
    		u.setBalance(10000);
    		u.setCode(0x08);
    		
    //		ATMThread a1 = new ATMThread("ATM1", u, 1000);
    //		ATMThread a2 = new ATMThread("ATM2", u, 5000);
    //		ATMThread a3 = new ATMThread("ATM3", u, 3000);
    //		a1.start();
    //		a2.start();
    //		a3.start();
    		final Thransfer t = new Thransfer();
    		for (int i = 0; i < 100; i++) {
    			new Thread(new Runnable() {
    				@Override
    				public void run() {
    					t.cre();
    				}
    			}).start();
    		}
    		while(Thread.activeCount()>1) {
    			Thread.yield();
    		}
    		System.out.println(t.it);
    	}
    	
    	public synchronized void cre() {
    		this.it++;
    	}
    }
    

    概念知识
    Java内存模型:

    1. 可见性
      线程之间的修改状态是可见的。也就是说一个线程修改的结果,另一个线程是立马可见的。比如volitile关键字,其修饰的变量不允许线程缓存和重排序,所以对其他线程是可见的,要注意不可分割性。
    2. 原子性
      原子是世界上最小的单位,具有不可分割性,那么我们称不可分割的操作为原子操作,n++和n=n+1都不属于原子操作,因为他是分割的。
    3. 有序性
      java提供二种方式来保证xi线程操作之间的有序性
    4. volitile本身具有禁止指令重拍的语义
    5. synchronization关键字在同一时间只允许一个线程进行操作,属于串行操作,保证线程间的有序性。

    参考链接

  • 相关阅读:
    期权标的概率密度函数
    Girsanov Theorem
    拉马努金恒等式
    波动率的三类模型
    stack(栈) and heap(堆)
    covar of lognormal variables
    BS 相关的一些近似公式
    布朗运动的一些特殊性质
    排序算法
    Mac node.js
  • 原文地址:https://www.cnblogs.com/kungFuPander/p/11711713.html
Copyright © 2011-2022 走看看