一、线程通信(线程交互):当多个线程完成某些特定任务的时候,线程之间有时也需要一定的通信,即线程通信 例如:模拟银行账户,用户A不断往该账户中存钱,最多存储10000元,若账户己满,需要通知用户B取钱 用户B不断从该账户中取钱,若余额不足时,需要通知用户A存钱 使用两个线程打印1-100,线程1、线程2 交替打印 二、在java.Long.Object类中 【等待唤醒机制】 wait():使当前"同步监视器"上的线程进入等待状态,同时释放锁 notify()/notifyAll():唤醒当前"同步监视器"上一个/所有 等待状态的线程 注意:上述方法必须使用在 同步中
package Thread;
/*
一、线程通信(线程交互):当多个线程完成某些特定任务的时候,线程之间有时也需要一定的通信,即线程通信
例如:模拟银行账户,用户A不断往该账户中存钱,最多存储10000元,若账户己满,需要通知用户B取钱
用户B不断从该账户中取钱,若余额不足时,需要通知用户A存钱
使用两个线程打印1-100,线程1、线程2 交替打印
二、在java.Long.Object类中
wait():使当前"同步监视器"上的线程进入等待状态
notify()/notifyAll():唤醒当前"同步监视器"上一个/所有 等待状态的线程
*/
public class WaitNotifyTest {
public static void main(String[] args) {
HelloThreadWait htw=new HelloThreadWait();
new Thread(htw).start();
new Thread(htw).start();
}
}
package Thread;
public class HelloThreadWait implements Runnable {
int i=0;
@Override
public void run() {
while (true){
synchronized (this){
this.notify();
if (i<=100){
System.out.println(Thread.currentThread().getName()+":"+i++);
}
try {
this.wait();
} catch (InterruptedException e) {
}
}
}
}
}
注意:
package Thread;
/*
一、线程通信(线程交互):当多个线程完成某些特定任务的时候,线程之间有时也需要一定的通信,即线程通信
例如:模拟银行账户,用户A不断往该账户中存钱,最多存储10000元,若账户己满,需要通知用户B取钱
用户B不断从该账户中取钱,若余额不足时,需要通知用户A存钱
使用两个线程打印1-100,线程1、线程2 交替打印
二、在java.Long.Object类中
【等待唤醒机制】
wait():使当前"同步监视器"上的线程进入等待状态,同时释放锁
notify()/notifyAll():唤醒当前"同步监视器"上一个/所有 等待状态的线程
注意:上述方法必须使用在 同步中
三、经典案例:消费者生产者案例
添加或创建数据的线程:生产者线程
删除或销毁数据的线程:消费者线程
*/
public class WaitNotifyTest {
public static void main(String[] args) {
/*HelloThreadWait htw=new HelloThreadWait();
new Thread(htw).start();
new Thread(htw).start();*/
Account account=new Account();
CustomerA ca=new CustomerA(account);
CustomerB cb=new CustomerB(account);
new Thread(ca,"用户A").start();
new Thread(cb,"用户B").start();
}
}
//账户
class Account{
private double balance;
public Account() {
}
public Account(double balance) {
this.balance = balance;
}
public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
//存款
public synchronized void deposit(double amount){
if (balance>=10000){
System.out.println("账户余额已满!");
try {
this.wait();
} catch (InterruptedException e) {
}
}else {
balance+=amount;
System.out.println(Thread.currentThread().getName()+": 成功存入"+amount+"余额为:"+balance);
this.notifyAll();
}
}
//取款
public synchronized void WithDraw(double amount){
if (balance<amount){
System.out.println("余额不足!");
try {
this.wait();
} catch (InterruptedException e) {
}
}else {
balance-=amount;
System.out.println(Thread.currentThread().getName()+": 成功取出"+amount+"余额为:"+balance);
this.notifyAll();
}
}
}
class CustomerA implements Runnable{
private Account account;
public CustomerA() {
}
public CustomerA(Account account) {
this.account = account;
}
public Account getAccount() {
return account;
}
public void setAccount(Account account) {
this.account = account;
}
@Override
public void run() {
while (true){
account.deposit(1000);
}
}
}
class CustomerB implements Runnable{
private Account account;
public CustomerB() {
}
public CustomerB(Account account) {
this.account = account;
}
public Account getAccount() {
return account;
}
public void setAccount(Account account) {
this.account = account;
}
@Override
public void run() {
while (true){
account.WithDraw(1000);
}
}
}
虚假唤醒
package Thread;
/*
一、线程通信(线程交互):当多个线程完成某些特定任务的时候,线程之间有时也需要一定的通信,即线程通信
例如:模拟银行账户,用户A不断往该账户中存钱,最多存储10000元,若账户己满,需要通知用户B取钱
用户B不断从该账户中取钱,若余额不足时,需要通知用户A存钱
使用两个线程打印1-100,线程1、线程2 交替打印
二、在java.Long.Object类中
【等待唤醒机制】
wait():使当前"同步监视器"上的线程进入等待状态,同时释放锁 需要使用在循环中,避免虚假唤醒
notify()/notifyAll():唤醒当前"同步监视器"上一个/所有 等待状态的线程
注意:上述方法必须使用在 同步中
三、经典案例:消费者生产者案例
添加或创建数据的线程:生产者线程
删除或销毁数据的线程:消费者线程
*/
public class WaitNotifyTest {
public static void main(String[] args) {
/*HelloThreadWait htw=new HelloThreadWait();
new Thread(htw).start();
new Thread(htw).start();*/
Account account=new Account();
CustomerA ca=new CustomerA(account);
CustomerB cb=new CustomerB(account);
new Thread(ca,"用户A").start();
new Thread(cb,"用户B").start();
}
}
//账户
class Account{
private double balance;
public Account() {
}
public Account(double balance) {
this.balance = balance;
}
public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
//存款
public synchronized void deposit(double amount){
while (balance>=10000){//wait() 需要使用在循环中,避免虚假唤醒
System.out.println("账户余额已满!");
try {
this.wait();
} catch (InterruptedException e) {
}
}
balance+=amount;
System.out.println(Thread.currentThread().getName()+": 成功存入"+amount+"余额为:"+balance);
this.notifyAll();
}
//取款
public synchronized void WithDraw(double amount){
while (balance<amount){
System.out.println("余额不足!");
try {
this.wait();
} catch (InterruptedException e) {
}
}
balance-=amount;
System.out.println(Thread.currentThread().getName()+": 成功取出"+amount+"余额为:"+balance);
this.notifyAll();
}
}
class CustomerA implements Runnable{
private Account account;
public CustomerA() {
}
public CustomerA(Account account) {
this.account = account;
}
public Account getAccount() {
return account;
}
public void setAccount(Account account) {
this.account = account;
}
@Override
public void run() {
while (true){
account.deposit(1000);
}
}
}
class CustomerB implements Runnable{
private Account account;
public CustomerB() {
}
public CustomerB(Account account) {
this.account = account;
}
public Account getAccount() {
return account;
}
public void setAccount(Account account) {
this.account = account;
}
@Override
public void run() {
while (true){
account.WithDraw(1000);
}
}
}