黑马程序员技术交流社区
标题:
多线程同步总结
[打印本页]
作者:
a80C51
时间:
2015-9-28 23:49
标题:
多线程同步总结
1)同步代码块
定义:使用同步监视器来解决线程冲突的问题,实现该同步监视器的通用方法。
2)语法结构
package com.example.bankthread;
public class BankAccountDrawThread extends Thread {
private BankAccount bankAccount;
private double drawAmount;
public BankAccountDrawThread(String name,BankAccount account,double drawAccount) {
// TODO Auto-generated constructor stub
super(name);
this.bankAccount = account;
this.drawAmount = drawAccount;
}
@Override
public void run() {
// TODO Auto-generated method stub
/*
* 使用bankAccount作为同步监视器,
* 任何线程在进入同步代码块之前,都会先获取对bankAccount的锁定,
* 此时,其他线程无法获得锁,也就无法修改它
*
*/
synchronized(bankAccount)
{
if(bankAccount.getBalance()>= drawAmount)
{
System.out.println(getName()+"取钱成功,出钞:"+drawAmount);
/* try {
Thread.sleep(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}*/
bankAccount.setBalance(bankAccount.getBalance()-drawAmount);
System.out.println("\t余额为:"+bankAccount.getBalance());
}
else
{
System.out.println(getName()+"取钱失败!余额不足!");
}
}
}
public static void main(String[] args) {
BankAccount bankAccount = new BankAccount("1234567", 10000);
new BankAccountDrawThread("甲", bankAccount, 8000).start();
new BankAccountDrawThread("乙", bankAccount, 8000).start();
}
}
复制代码
3)所代表含义
线程开始执行同步代码块之前,必须先获得对同步监视器的锁定。
4)逻辑思想
加锁---》修改---》释放锁。
5)同步方法:
使用synchronized关键字来修饰某个方法
6)语法结构
package com.example.bankthread;
public class AccountDrawThread extends Thread {
private Account account;
private double drawAmount;
//设置线程的名字,对应的账户及所需取得钱
public AccountDrawThread(String name,Account account,double drawAmount) {
super(name);//调用父类Thread类中的方法,为线程指定线程名称
this.account = account;
this.drawAmount = drawAmount;
}
@Override
public void run() {
// TODO Auto-generated method stub
/*
* 由于draw()方法,使用synchronized修饰,故此时同步监视器是this,
* 故多线程在调用该accoun时,必须先对account对象加锁
*/
account.draw(drawAmount);
}
}
复制代码
7)对于synchronized修饰的实例方法而言,无须显示的指定同步监视器,其监视器是this引用指代的对象。
8)线程安全的类的特征:
A,该类的对象可以被多个线程安全地访问;
B,每个线程调用该对象的任意方法后,都将得到正确的结果;
C,每个线程调用该对象的任意方法后,该对象依然保持合理状态。
9)为了减少为实现线程安全而带来的运行效率的损失,线程通常采用如下策略:
A,不要对线程安全类的所有方法进行同步,只对那些会改变竞争资源(共享资源)的方法进行同步控制;
B,如果可变类有两种运行环境:单线程和多线程,则应该为该可变类通过两个版本——线程安全版本及线程不安全版本。单线程时,使用线程不安全版本;多线程时,使用线程安全版本。
10)同步监视器的锁定释放
释放情形如下:
A,当前线程的同步方法、同步代码块执行结束;
B,当前线程的同步方法、同步代码块遇到了break或者continue等终止运行;
C,当前线程的同步方法、同步代码块出现了未处理的Error或Exception,导致了代码块或方法异常结束时;
D,当前线程执行同步代码块或者同步方法时,程序执行同步监视器对象的wait()方法,当前线程暂停。
不会释放的情形:
A,线程执行同步代码块或者同步方法时,程序调用Thread.sleep()、Thread.yield()方法来暂停当前线程的执行,当前线程不会释放同步监视器;
B,线程执行同步代码块是,其他线程调用了该线程的suspend()方法,将线程挂起,该线程不会释放同步监视器。
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2