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. 小结
    • 线程的同步是为了防止多线程访问同一个资源是对资源的破坏
    • 运行在非静态同步方法时获得的是对象锁
    • 运行在静态同步方法时获得的时类对象锁
    • 类对象锁和对象锁互不影响,一个线程可以获取多个锁
    • 对于同步,时刻要明白是在那个对象之上的同步
    • 多个线程争夺一个资源对象时,会造成线程阻塞的问题
    • 死锁是多个线程相互等待造成的
  • 相关阅读:
    Java vs Python
    Compiled Language vs Scripting Language
    445. Add Two Numbers II
    213. House Robber II
    198. House Robber
    276. Paint Fence
    77. Combinations
    54. Spiral Matrix
    82. Remove Duplicates from Sorted List II
    80. Remove Duplicates from Sorted Array II
  • 原文地址:https://www.cnblogs.com/kungFuPander/p/11711692.html
Copyright © 2011-2022 走看看