多线程(5)同步

版权声明:本文为博主原创文章,欢迎转载。 https://blog.csdn.net/xurk0922/article/details/73723502

当多个线程来访问同一个数据时非常容易出现线程安全问题。
同步:一个任务的完成需要依赖另一个任务时,只有等待被依赖的那个任务完成后,依赖的任务才能完成。要不都完成要不都失败。
举例:有两个a和b,都是向同一个账号取钱,假设账户中有800,a和b都是取800;因为线程时并发运行的,所以可能会发生在a取800但还没进行扣款b来取800了,最后a和b都完成了取钱,这显然是不正常的。
发生这个问题的原因是任务中存在两个操作,取钱和扣钱,在未同步的情况下没有一起完成就切换了线程。

同步代码块

因为run方法体内不同步安全性,为了解决这个问题,需要同步监视器来解决这个问题,使用的通用就是同步。

synchronized (obj) {
    // 需要同步的内容
    // 取钱
    // 扣钱
    // 要么一起完成,要么一起失败
}

同步代码块中使用共享资源资源作为同步监视器(就是上面那个obj),这样其实是在修改共享资源之前先加锁在修改完成之后释放锁。通过这种方式可以保证在任一时刻都只有一个线程操作该共享资源。
通常同步代码块存在于run方法体的开始到结束。

同步方法

使用synchronized关键字修饰某个方法时,这个方法成了同步方法。对于同步方法而言,不用显示的制定同步监视器,因为该方法存在的对象就是同步方法的同步监视器。
synchronized可以修饰方法、代码块,不能修饰类、构造器等

同步锁(Lock)

在jdk1.5,java提供另一种线程同步:它通过定义同步锁对象来实现同步。
Lock提供了比synchronized更广泛、灵活的操作方式。
在临界区之前使用lock.lock();临界区之后使用lock.unlock();

线程安全的类具有的特点

  1. 该类的对象可以被多个线程安全的访问;
  2. 每个调用对象的任意方法之后都将得到正确的结果;
  3. 每个调用对象的任意方法之后该对象保持合理状态。

释放同步监视器的情况:

  1. 当线程的同步代码块、同步方法执行结束;
  2. 执行了wait方法;

猜你喜欢

转载自blog.csdn.net/xurk0922/article/details/73723502