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;}}

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 华为7x金属外壳掉漆了怎么办 华为麦芒6连接蓝牙音响卡顿怎么办 华为芒麦6恢复出厂设置怎么办 华为麦芒4下拉通知栏没反应怎么办 怎么看华为麦芒6信号差怎么办 华为手机锁屏密码忘了怎么办 苹果手机进水后手机卡无服务怎么办 摩拜单车绑定的手机号注销了怎么办 摩拜单车注册的手机号注销了怎么办 摩拜单车注册手机号换了怎么办 被手机店骗话费送合约机怎么办 机蜜租赁的手机丢了怎么办 合约机返话费手机掉了怎么办 手机摔坏了开不了机怎么办 华为魅特10屏幕锁住了怎么办 电信送的路由器只有一个端口怎么办 苹果手机5c屏幕死机了怎么办 日版苹果手机显示无服务怎么办 iphone有锁4g变3g怎么办 耳机胶套脱落掉入耳朵怎么办 苹果笔记本电用完了开机了怎么办 华为荣耀5x锁屏密码忘了怎么办 华为荣耀锁屏密码忘了怎么办 华为手机屏锁密码忘了怎么办 华为荣耀9青春版相机很模糊怎么办 华为荣耀7手机照相忽然模糊怎么办 苹果5s进水开不了机怎么办 红米4a玩王者荣耀卡怎么办 老是显示媒体存储以停止运行怎么办 支付宝邮二维码地址留错了怎么办 华为畅享5s太卡怎么办 金立手机导航gps信号弱怎么办 贴了膜后边缘有气泡怎么办 魅族mx5刷机失败然后黑屏怎么办 魅族手机无线网玩王者卡怎么办 魅族手机玩王者荣耀卡怎么办 魅族手机导航gps信号弱怎么办 魅族手机4g信号差怎么办 魅族手机下面一排键失灵怎么办 魅族手机冲不进去电怎么办 苹果账号付款了又让付款怎么办