线程的同步和锁

问题引出

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

问题解决

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. 小结
  • 线程的同步是为了防止多线程访问同一个资源是对资源的破坏
  • 运行在非静态同步方法时获得的是对象锁
  • 运行在静态同步方法时获得的时类对象锁
  • 类对象锁和对象锁互不影响,一个线程可以获取多个锁
  • 对于同步,时刻要明白是在那个对象之上的同步
  • 多个线程争夺一个资源对象时,会造成线程阻塞的问题
  • 死锁是多个线程相互等待造成的
posted @ 2019-10-21 09:44  kungFuPander  阅读(148)  评论(0编辑  收藏  举报