Java的多线程之同步篇二:synchronized关键字
来源:互联网 发布:中文域名交易中心 编辑:程序博客网 时间:2024/05/21 17:40
一、synchronized关键字
Lock和Condition接口为程序设计人员提供了高度的锁定控制。然而,大多数情况下,并不需要那样的控制,并且可以使用一种嵌入到Java语言内部的机制。从1.0版开始,Java中的每一个对象都有一个内部锁。如果一个方法用synchronized关键字声明,那么对象的锁将保护整个方法。也就是说,要调用该方法,线程必须获得内部的对象锁。
换句话说:
public synchronized void method(){method body}等价于public void method(){this.intrinsicLock.lock();try{method body}finally{ this.intrinsicLock.unlock();}}内部对象锁只有一个相关条件。wait方法添加一个线程到等待集中,notifyAll/notify方法解除等待线程的阻塞状态。换句话说:调用wait或notifyAll等价于intrinsicCondition.await(); intrinsicCondition.signalAll();
注:wait、notifyAll以及notify方法是Object类的final方法。Condition方法必须被命名为await、signalAll和signal以便它们不会与那些方法发生冲突。
修改后的Bank类如下:
public synchronized void transfer(int from, int to, double amount)throws InterruptedException {while (accounts[from] < amount)wait();accounts[from] -= amount;accounts[to] += amount;notifyAll();}public synchronized double getTotalBalance() {double sum = 0;for (double a : accounts) {sum += a;}return sum;}使用synchronized关键字编写代码要简洁的多。当然,必须了解每个对象有一个内部锁,并且该锁有一个内部条件。由锁来管理那些试图进入synchronized方法的线程,有条件来管理那些试图调用wait的线程。
将静态方法声明为synchronized也是合法的。如果调用这种方法,该方法获得相关的类对象的内部锁。如果类对象的内部锁被锁住,没有其他的线程可以调用同一个类的这个或任何其他的同步静态方法。
注:内部锁和条件存在一些局限。包括:
a>不能中断一个正在试图获得锁的线程。
b>试图获得锁时不能设定超时。
c>每个锁仅有单一的条件,可能是不够的。
在代码中应该使用哪一种?Lock和Condition对象还是同步方法?建议如下:
i>最好既不使用Lock/Condition也不使用synchronized关键字。在许多情况下你可以使用java.util.concurrent包中的一种机制,它会为你处理所有的加锁。
ii>如果synchronized关键字适合你的程序,那么请尽量使用它,这样可以减少编写的代码数量,减少出错的几率。
iii>如果特别需要Lock/Condition结构提供的独有特性,才使用Lock/Condition。
常用方法:notifyAll() 、notify() 、wait()
解除或导致线程的阻塞状态,以上方法只能在同步方法或同步代码块中调用(即:使用synchronized关键字的地方)。如果当前线程不是对象锁的持有者,该方法抛出一个IllegalMonitorStateException异常。
修改Bank的代码如下:
package com.thread.bank.syn;public class Bank {private final double[] accounts;public Bank(int n, double initialBalance) {accounts = new double[n];for (int i = 0; i < accounts.length; i++) {accounts[i] = initialBalance;}}public synchronized void transfer(int from, int to, double amount)throws InterruptedException {while (accounts[from] < amount)wait();System.out.print(Thread.currentThread());accounts[from] -= amount;System.out.printf(" %10.2f from %d to %d", amount, from, to);accounts[to] += amount;System.out.printf(" Total Balance: %10.2f%n", getTotalBalance());notifyAll();}public synchronized double getTotalBalance() {double sum = 0;for (double a : accounts) {sum += a;}return sum;}public int size() {return accounts.length;}}
- Java的多线程之同步篇二:synchronized关键字
- Java多线程同步 synchronized 关键字的使用
- Java多线程同步 synchronized关键字
- Java 多线程:synchronized 多线程同步关键字
- Java 多线程:synchronized 多线程同步关键字
- 记录Java多线程的同步问题---synchronized关键字的使用
- Java多线程之synchronized关键字
- JAVA多线程之Synchronized关键字
- Java多线程:线程同步与关键字synchronized
- (二)java多线程之synchronized
- JAVA同步之 synchronized关键字详解
- Java并发编程之同步关键字synchronized
- Java 多线程编程之三:synchronized 关键字的使用
- JAVA之旅(十三)——线程的安全性,synchronized关键字,多线程同步代码块,同步函数,同步函数的锁是this
- Java多线程之同步关键字
- android 多线程同步-synchronized关键字
- Java多线程系列--“基础篇”04之 synchronized关键字
- Java多线程系列--“基础篇”04之 synchronized关键字 (r)
- rquest.getRemoteAddr()获取的值为0:0:0:0:0:0:0:1
- Light OJ 1122 Digit Count (简单数位DP)
- 架构设计三部曲之如何评审架构设计说明书
- hdu1140 war on weather
- 学业众筹,为着闪亮的日子
- Java的多线程之同步篇二:synchronized关键字
- docker 学习笔记 -----如何批量删除的已经处于停止状态的容器
- Linux进程共享通信 -- mmap实现
- BZOJ1117 POI2009 救火站
- <LeetCode OJ> 290. Word Pattern
- Linux服务管理命令
- C语言连接mysql数据库查询中文的数据表乱码问题
- Volley get请求上传中文参数,后台接收到的是乱码的解决办法
- 1. 判断用户输入是否符合预期的循环