100个线程同时向一个银行账户中存入1元钱
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* java编程题:100个线程同时向一个银行账户中存入1元钱
*/
public class Test {
public static void main(String[] args) {
Account account = new Account();
ExecutorService service = Executors.newFixedThreadPool(100);
for (int i = 1; i <= 100; i++) {
service.execute(new MoneyThread(account, 1));
}
service.shutdown();
while(!service.isTerminated()){}
System.out.println("账户金额:"+account.getBalance());
}
}
/**
* 银行账户类
*/
class Account {
private double balance; //账户余额
private Lock accountLock = new ReentrantLock(); //锁对象
/**
* 存入金额方法
*
* 实现方式1:
* synchronized关键字修饰方法为同步方法
*
public synchronized void deposit(double money) {
double newBalance = balance + money;
try {
Thread.sleep(10); //模拟此业务需要处理时间
} catch (InterruptedException e) {
e.printStackTrace();
}
balance = newBalance;
}
*/
/**
* 存入金额方法
*
* 实现方式2:
* 通过JDK1.5显示式锁机制,为每个银行账户创建一个锁对象,在存款操作时进行加锁和解锁的操作。
*/
public void deposit(double money) {
accountLock.lock(); //加锁
double newBalance = balance + money;
try {
Thread.sleep(10); //模拟此业务需要处理时间
} catch (InterruptedException e) {
e.printStackTrace();
}
balance = newBalance;
accountLock.unlock(); //解锁
}
/**
* 获得账户金额
*/
public double getBalance() {
return balance;
}
}
/**
* 存钱线程类
*/
class MoneyThread implements Runnable {
private Account account; //存入账户
private double money; //存入金额
public MoneyThread(Account account, double money) {
this.account = account;
this.money = money;
}
@Override
public void run() {
account.deposit(money);
}
}
synchronized 实现两个线程交替执行
package com.example.lum.myapplicationthread;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import java.util.concurrent.ThreadLocalRandom;
public class MainActivity extends AppCompatActivity {
private static int num = 0;
Object lock = new Object(); //定义任意对象作为锁对象
private boolean islocked = false; //定义一个boolean的变量
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new ThreadZreo().start(); //创建打印 0 的线程
new ThreadOne().start();//创建打印 1 的线程
}
public class ThreadZreo extends Thread {
@Override
public void run() {
while(num++ < 20) {
synchronized (lock) {// 将要同步的代码放到 synchronized lock 方法里,同一个lock 对象只能一时间被一个synchronized 方法所拥有
if (islocked) { //判断是否上锁
try {
lock.wait(); //将这个线程等待,允许别的线程拥有 lock 锁对象, 可以被 唤醒
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
System.out.println("我是 0 线程");
islocked = true; //把自己给 wait
lock.notifyAll(); //唤醒拥有 lock 锁对象的 wait 线程
}
}
}
}
}
public class ThreadOne extends Thread {
@Override
public void run () {
while (num++ < 20) {
synchronized (lock) {
if (islocked) {
System.out.println("我是 1 线程");
islocked = false; //把自己给 wait
lock.notifyAll(); //唤醒拥有 lock 锁对象的 wait 线程
} else {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
}
注意事项
1)synchronized (lock) 其中锁对象,一次只能在一个 synchronized 方法里调用
当一个 synchronized 方法阻塞,并且没有释放 lock 对象,则 另一个 synchronized ()方法无法执行
2) lock.wait() 本线程等待,别的synchronized (lock) 线程运行 。lock.wait(2000);表示等待2s后执行下面代码,期间可被唤醒。
3)lock.notifyAll() 可以唤醒 在lock 对象上 wait 的所有线程
4)lock.wait() lock.notifyAll() 都必须在 synchronized (lock ) {} 函数之中
即使单纯的唤醒操作
synchronized (lock ) {
lock.notifyAll();
}