Java线程小结(二)(二)

2014-11-24 08:54:10 · 作者: · 浏览: 5
it(mills)方法
都是等待指定时间后自动苏醒,调用wait方法的当前线程会释放该同步监视器的锁定,可以不用notify或notifyAll方法把它唤醒。
notify()
唤醒在同步监视器上等待的单个线程,如果所有线程都在同步监视器上等待,则会选择唤醒其中一个线程,选择是任意性的,只有当前线程放弃对该同步监视器的锁定后,也就是使用wait方法后,才可以执行被唤醒的线程。
notifyAll()方法
唤醒在同步监视器上等待的所有的线程。只用当前线程放弃对该同步监视器的锁定后,才可以执行被唤醒的线程
案例:
package com.xiaomo.thread;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Account {
// 封装账户编号,账户余额两个Field
private String accountNo;
private double balance;
// 账户中是否已有存款的标志
private boolean flag = false;
// 显示定义Lock对象
private final Lock lock = new ReentrantLock();
// 获得指定Lock对象对应Condition
private final Condition cond = lock.newCondition();
// 定义锁对象
private final ReentrantLock relock = new ReentrantLock();
// 构造器
public Account() {
}
public Account(String accountNo, double balance) {
this.setAccountNo(accountNo);
this.setBalance(balance);
}
public int hashCode() {
return accountNo.hashCode();
}
// 下面两个方法根据accountNo来重写hashCode()和equals()方法
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj != null && obj.getClass() == Account.class) {
Account target = (Account) obj;
return target.getAccountNo().equals(accountNo);
}
return false;
}
// 提供一个线程安全的draw方法来完成取钱操作(同步方法)
public synchronized void draw(double drawAmount) {
// 账户余额大于取钱数目
if (balance >= drawAmount) {
// 吐出真钞
System.out.println(Thread.currentThread().getName() + "取钱成功!吐出真钞:"
+ drawAmount);
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 修改余额
balance -= drawAmount;
System.out.println("\t 余额为:" + balance);
} else {
System.out.println(Thread.currentThread().getName() + "取钱失败!余额不足!");
}
}
// 提供一个线程安全的draw方法来完成取钱操作(同步锁)
public void acquire(double drawAmount) {
// 加锁
relock.lock();
try {
if (balance >= drawAmount) {
// 吐出真钞
System.out.println(Thread.currentThread().getName()
+ "取钱成功!吐出真钞:" + drawAmount);
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 修改余额
balance -= drawAmount;
System.out.println("\t 余额为:" + balance);
} else {
System.out.println(Thread.currentThread().getName()
+ "取钱失败!余额不足!");
}
} finally {
// 修改完成,释放锁
relock.unlock();
}
}
// 同步方法的线程通信方式
public synchronized void get(double drawAmount) {
try {
// 如果flag为false,表明账户中还没有人存钱进去,取钱方法阻塞
if (!flag) {
this.wait();
} else {
if (balance >= drawAmount) {
// 执行取钱操作
System.out.println(Thread.currentThread().getName() + "取钱:"
+ drawAmount);
balance -= drawAmount;
System.out.println("账户余额为:" + balance);
// 将标志账户是否已有存款的标志设为false
flag = false;
// 唤醒其他线程
this.notifyAll();
} else {
System.out.println(Thread.currentThread().getName()
+ "取钱失败!余额不足!");
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 同步方法的线程通信方式
public synchronized void deposit(double drawAmount) {
try {
// 如果flag为true,表明账户中已有人存钱进去,存钱方法阻塞
if (flag) {
this.wait();
} else {
// 执行存款操作
Sys