zoukankan      html  css  js  c++  java
  • 线程的同步和锁

    问题引出

    为避免多线程对同一个对象进行操作,对数据造成的破坏。

    问题解决

    public class Tt extends Thread{
    	private Money money;
    	
    	public Tt(Money money) {
    		this.money = money;
    	}
    	
    	@Override
    	public void run() {
    		for (int i = 0; i < 3; i++) {
    			this.takeIt(30);
    			System.out.println(Thread.currentThread().getName()+"->"+money.getMoney());
    		}
    	}
    	
    	public int takeIt(int x) {
    		return  money.takeIt(x);
    	}
    	
    	public static void main(String[] args) {
    		Money m = new Money();
    		Tt t1 = new Tt(m);
    		Tt t2 = new Tt(m);
    		t1.start();
    		t2.start();
    	}
    }
    
    • 确定资源对象为同一个对象

    同步和锁定

    1. 非静态方法同步
    • 只能同步方法,不能同步属性和类
    • 只有拿到锁的线程才会执行方法,其余线程进入到阻塞状态
    • 只针对同步方法,非同步方法不受锁的约束
    • 如果持锁线程睡眠(sleep),其所持锁不会释放
    • 线程可以获得多个锁,比如在一个同步方法中调用另一个同步方法,该线程同时持有二个对象的锁
    • 线程同步埙害并发性,应尽量缩小同步的范围
    • 使用同步代码块的时候,应确定在那个对象上同步,也就是获取那个对象的锁,效果等同于同步整个方法,但范围缩小了.
    1. 静态方法同步
    • 用于整个类对象的锁,这个对象就是这个类(xx.class)
    1. 何时需要同步
      当多个线程之间存在可交换的数据时,为保证该数据的唯一性及准确性,避免多个线程同时修改他而造成的资源破坏问题.
    2. 未获得锁线程状态
      会进入到阻塞状态,知道持有锁的线程释放,线程变为等待可运行或运行.
      当考虑阻塞时,一定要注意那个对象正在被锁定
    • 运行在同一个对象的非静态同步方法线程将会阻塞
    • 运行在同一个类中静态同步方法的线程将会阻塞
    • 运行在一个类中的静态同步方法和非静态方法永远不会阻塞
    • 运行在不同对象的同一个同步方法将永远不会阻塞
    1. 线程安全类
    • 没有绝对的安全
    1. 小结
    • 线程的同步是为了防止多线程访问同一个资源是对资源的破坏
    • 运行在非静态同步方法时获得的是对象锁
    • 运行在静态同步方法时获得的时类对象锁
    • 类对象锁和对象锁互不影响,一个线程可以获取多个锁
    • 对于同步,时刻要明白是在那个对象之上的同步
    • 多个线程争夺一个资源对象时,会造成线程阻塞的问题
    • 死锁是多个线程相互等待造成的
  • 相关阅读:
    2018 桂林ccpc现场赛 总结
    2018 南京icpc现场赛总结
    nowcoder 203J Graph Coloring I(dfs)
    nowcoder 203A Knight(贪心+打表)
    nowcoder 202H-卡牌游戏
    nowcoder 202F-平衡二叉树
    topcoder srm 738 div1 FindThePerfectTriangle(枚举)
    codeforces 1041 E.Vasya and Good Sequences(暴力?)
    hdu 3507 Print Article(dp+斜率优化)
    hdu 1007 Quoit Design(分治)
  • 原文地址:https://www.cnblogs.com/kungFuPander/p/11711692.html
Copyright © 2011-2022 走看看