继承Thread:
package Bank_extends;
public class Bank {
// 定义静态变量
static int money = 1000;
// 柜台Counter取钱的方法
public void Counter(int money) {// 参数是每次取走的钱
Bank.money -= money;//取钱后总数减少
System.out.println("A取走了" + money + "还剩下" + (Bank.money));
}
// ATM取钱的方法
public void ATM(int money) {// 参数是每次取走的钱
Bank.money -= money;//取钱后总数减少
System.out.println("B取走了" + money + "还剩下" + (Bank.money));
}
}
package Bank_extends;
public class MainClass {
public static void main(String[] args) {
/**
* 两个人AB通过一个账户A在柜台取钱和B在ATM机取钱
* */
// 实力化一个银行对象
Bank bank = new Bank();
// 实例化两个人,传入同一个银行的对象
PersonA pA = new PersonA(bank);
PersonB pB = new PersonB(bank);
// 两个人开始取钱
pA.start();
pB.start();
}
}
package Bank_extends;
public class PersonA extends Thread{
Bank bank;
// 通过构造器传入银行对象,确保两个人进入的是一个银行
public PersonA(Bank bank) {
this.bank = bank;
}
//重写run方法,在里面实现使用柜台取钱
@Override
public void run() {
while (Bank.money >= 100) {
bank.Counter(100);// 每次取100块
try {
sleep(100);// 取完休息0.1秒
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
package Bank_extends;
public class PersonB extends Thread{
Bank bank;
// 通过构造器传入银行对象,确保两个人进入的是一个银行
public PersonB(Bank bank) {
this.bank = bank;
}
// 重写run方法,在里面实现使用柜台取钱
@Override
public void run() {
while (Bank.money >= 200) {
bank.ATM(200);// 每次取200块
try {
sleep(100);// 取完休息0.1秒
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
打印结果:
实现Runnable接口:
package Bank_imp;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Bank {
/**
* 1、提供方法给每条线程返回当前总金额。
* @return
*/
private int moneyAll = 1000; // 总金额
public int getMoneyAll() {
return moneyAll;
}
/**
* 2、提供方法给每条线程返回同一把锁。
* 通过柜台orATM取钱,都必须同步所有取钱的动作。
* @return
*/
private Lock lock = new ReentrantLock();// 取钱时上锁
public Lock getLock(){
return lock;
}
// 柜台Counter取钱的方法
public void Counter(int money) {
moneyAll -= money;//取钱后总数减少
System.out.println("线程 "+Thread.currentThread().getName()+"从柜台取走了" + money + "还剩下" + (moneyAll));
}
// ATM取钱的方法
public void ATM(int money) {// 参数是每次取走的钱
moneyAll -= money;//取钱后总数减少
System.out.println("线程 "+Thread.currentThread().getName()+"从ATM取走了" + money + "还剩下" + (moneyAll));
}
}
package Bank_imp;
public class MainClass {
public static void main(String[] args) {
// 实力化一个银行对象
Bank bank = new Bank();
/**
* 这里区别与 继承Thread:
* 定义为柜台、ATM两种取钱方式
* 传入同一个银行的对象
*/
PersonA pA = new PersonA(bank);
PersonB pB = new PersonB(bank);
/**
* 自定义线程数量,每个线程是一次取钱动作。
* 传入取钱方式。
*/
Thread t1 = new Thread(pA);
Thread t2 = new Thread(pA);
Thread t3 = new Thread(pB);
Thread t4 = new Thread(pB);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
package Bank_imp;
public class PersonA implements Runnable{ // 实现Runnable
private Bank bank;
public PersonA(Bank bank) {
this.bank = bank;
}
private int quMoney = 20;// 取钱金额
@Override
public void run() {
A:while(true){
System.out.println("线程 "+Thread.currentThread().getName()+" 进入 A用户");
bank.getLock().lock();// 拿锁
int moneyAll = bank.getMoneyAll();
while(moneyAll<quMoney){
System.out.println("线程 "+Thread.currentThread().getName()+" 关闭");
bank.getLock().unlock();// 关闭线程前,解锁
break A;
}
System.out.println("线程 "+Thread.currentThread().getName()+"------可以取的钱:"+moneyAll);
bank.Counter(quMoney);
bank.getLock().unlock();// 取完钱,还锁
}
}
}
package Bank_imp;
public class PersonB extends Thread{
private Bank bank;
public PersonB(Bank bank) {
this.bank = bank;
}
private int quMoney = 70;// 取钱金额
@Override
public void run() {
A:while(true){
System.out.println("线程 "+Thread.currentThread().getName()+" 进入 B用户");
bank.getLock().lock();// 拿锁
int moneyAll = bank.getMoneyAll();
while(moneyAll<quMoney){
System.out.println("线程 "+Thread.currentThread().getName()+" 关闭");
bank.getLock().unlock();// 关闭线程前,解锁
break A;
}
System.out.println("线程 "+Thread.currentThread().getName()+"------可以取的钱:"+moneyAll);
bank.ATM(quMoney);
bank.getLock().unlock();// 取完钱,还锁
}
}
}
打印结果一:
线程 Thread-1 进入 A用户
线程 Thread-1------可以取的钱:1000
线程 Thread-1从柜台取走了20还剩下980
线程 Thread-1 进入 A用户
线程 Thread-1------可以取的钱:980
线程 Thread-1从柜台取走了20还剩下960
线程 Thread-1 进入 A用户
线程 Thread-1------可以取的钱:960
线程 Thread-1从柜台取走了20还剩下940
线程 Thread-1 进入 A用户
线程 Thread-1------可以取的钱:940
线程 Thread-1从柜台取走了20还剩下920
线程 Thread-1 进入 A用户
线程 Thread-1------可以取的钱:920
线程 Thread-1从柜台取走了20还剩下900
线程 Thread-1 进入 A用户
线程 Thread-1------可以取的钱:900
线程 Thread-1从柜台取走了20还剩下880
线程 Thread-1 进入 A用户
线程 Thread-1------可以取的钱:880
线程 Thread-1从柜台取走了20还剩下860
线程 Thread-1 进入 A用户
线程 Thread-1------可以取的钱:860
线程 Thread-1从柜台取走了20还剩下840
线程 Thread-3 进入 B用户
线程 Thread-4 进入 B用户
线程 Thread-3------可以取的钱:840
线程 Thread-3从ATM取走了70还剩下770
线程 Thread-2 进入 A用户
线程 Thread-2------可以取的钱:770
线程 Thread-2从柜台取走了20还剩下750
线程 Thread-2 进入 A用户
线程 Thread-1 进入 A用户
线程 Thread-3 进入 B用户
线程 Thread-4------可以取的钱:750
线程 Thread-4从ATM取走了70还剩下680
线程 Thread-4 进入 B用户
线程 Thread-2------可以取的钱:680
线程 Thread-2从柜台取走了20还剩下660
线程 Thread-2 进入 A用户
线程 Thread-2------可以取的钱:660
线程 Thread-2从柜台取走了20还剩下640
线程 Thread-2 进入 A用户
线程 Thread-1------可以取的钱:640
线程 Thread-1从柜台取走了20还剩下620
线程 Thread-1 进入 A用户
线程 Thread-1------可以取的钱:620
线程 Thread-1从柜台取走了20还剩下600
线程 Thread-1 进入 A用户
线程 Thread-3------可以取的钱:600
线程 Thread-3从ATM取走了70还剩下530
线程 Thread-3 进入 B用户
线程 Thread-4------可以取的钱:530
线程 Thread-4从ATM取走了70还剩下460
线程 Thread-4 进入 B用户
线程 Thread-2------可以取的钱:460
线程 Thread-2从柜台取走了20还剩下440
线程 Thread-2 进入 A用户
线程 Thread-1------可以取的钱:440
线程 Thread-1从柜台取走了20还剩下420
线程 Thread-1 进入 A用户
线程 Thread-3------可以取的钱:420
线程 Thread-3从ATM取走了70还剩下350
线程 Thread-3 进入 B用户
线程 Thread-4------可以取的钱:350
线程 Thread-4从ATM取走了70还剩下280
线程 Thread-4 进入 B用户
线程 Thread-2------可以取的钱:280
线程 Thread-2从柜台取走了20还剩下260
线程 Thread-2 进入 A用户
线程 Thread-2------可以取的钱:260
线程 Thread-2从柜台取走了20还剩下240
线程 Thread-2 进入 A用户
线程 Thread-1------可以取的钱:240
线程 Thread-1从柜台取走了20还剩下220
线程 Thread-1 进入 A用户
线程 Thread-3------可以取的钱:220
线程 Thread-3从ATM取走了70还剩下150
线程 Thread-3 进入 B用户
线程 Thread-4------可以取的钱:150
线程 Thread-4从ATM取走了70还剩下80
线程 Thread-4 进入 B用户
线程 Thread-2------可以取的钱:80
线程 Thread-2从柜台取走了20还剩下60
线程 Thread-2 进入 A用户
线程 Thread-1------可以取的钱:60
线程 Thread-1从柜台取走了20还剩下40
线程 Thread-1 进入 A用户
线程 Thread-1------可以取的钱:40
线程 Thread-1从柜台取走了20还剩下20
线程 Thread-1 进入 A用户
线程 Thread-3 关闭
线程 Thread-4 关闭
线程 Thread-2------可以取的钱:20
线程 Thread-2从柜台取走了20还剩下0
线程 Thread-1 关闭
线程 Thread-2 进入 A用户
线程 Thread-2 关闭
打印结果二:
线程 Thread-1 进入 A用户
线程 Thread-1------可以取的钱:1000
线程 Thread-1从柜台取走了20还剩下980
线程 Thread-1 进入 A用户
线程 Thread-1------可以取的钱:980
线程 Thread-1从柜台取走了20还剩下960
线程 Thread-1 进入 A用户
线程 Thread-1------可以取的钱:960
线程 Thread-1从柜台取走了20还剩下940
线程 Thread-2 进入 A用户
线程 Thread-2------可以取的钱:940
线程 Thread-2从柜台取走了20还剩下920
线程 Thread-2 进入 A用户
线程 Thread-2------可以取的钱:920
线程 Thread-2从柜台取走了20还剩下900
线程 Thread-2 进入 A用户
线程 Thread-2------可以取的钱:900
线程 Thread-2从柜台取走了20还剩下880
线程 Thread-1 进入 A用户
线程 Thread-2 进入 A用户
线程 Thread-4 进入 B用户
线程 Thread-1------可以取的钱:880
线程 Thread-1从柜台取走了20还剩下860
线程 Thread-3 进入 B用户
线程 Thread-3------可以取的钱:860
线程 Thread-1 进入 A用户
线程 Thread-3从ATM取走了70还剩下790
线程 Thread-2------可以取的钱:790
线程 Thread-3 进入 B用户
线程 Thread-2从柜台取走了20还剩下770
线程 Thread-2 进入 A用户
线程 Thread-2------可以取的钱:770
线程 Thread-2从柜台取走了20还剩下750
线程 Thread-4------可以取的钱:750
线程 Thread-4从ATM取走了70还剩下680
线程 Thread-4 进入 B用户
线程 Thread-2 进入 A用户
线程 Thread-4------可以取的钱:680
线程 Thread-4从ATM取走了70还剩下610
线程 Thread-4 进入 B用户
线程 Thread-1------可以取的钱:610
线程 Thread-1从柜台取走了20还剩下590
线程 Thread-1 进入 A用户
线程 Thread-1------可以取的钱:590
线程 Thread-1从柜台取走了20还剩下570
线程 Thread-1 进入 A用户
线程 Thread-3------可以取的钱:570
线程 Thread-3从ATM取走了70还剩下500
线程 Thread-3 进入 B用户
线程 Thread-3------可以取的钱:500
线程 Thread-3从ATM取走了70还剩下430
线程 Thread-3 进入 B用户
线程 Thread-2------可以取的钱:430
线程 Thread-2从柜台取走了20还剩下410
线程 Thread-2 进入 A用户
线程 Thread-2------可以取的钱:410
线程 Thread-2从柜台取走了20还剩下390
线程 Thread-2 进入 A用户
线程 Thread-4------可以取的钱:390
线程 Thread-4从ATM取走了70还剩下320
线程 Thread-4 进入 B用户
线程 Thread-4------可以取的钱:320
线程 Thread-4从ATM取走了70还剩下250
线程 Thread-4 进入 B用户
线程 Thread-4------可以取的钱:250
线程 Thread-4从ATM取走了70还剩下180
线程 Thread-4 进入 B用户
线程 Thread-4------可以取的钱:180
线程 Thread-4从ATM取走了70还剩下110
线程 Thread-4 进入 B用户
线程 Thread-1------可以取的钱:110
线程 Thread-1从柜台取走了20还剩下90
线程 Thread-1 进入 A用户
线程 Thread-1------可以取的钱:90
线程 Thread-1从柜台取走了20还剩下70
线程 Thread-1 进入 A用户
线程 Thread-1------可以取的钱:70
线程 Thread-1从柜台取走了20还剩下50
线程 Thread-1 进入 A用户
线程 Thread-1------可以取的钱:50
线程 Thread-1从柜台取走了20还剩下30
线程 Thread-1 进入 A用户
线程 Thread-1------可以取的钱:30
线程 Thread-1从柜台取走了20还剩下10
线程 Thread-1 进入 A用户
线程 Thread-1 关闭
线程 Thread-3 关闭
线程 Thread-2 关闭
线程 Thread-4 关闭
总结:
继承Thread的逻辑:
1.每个run方法单独运行,且只能运行一个线程。
2.为了满足不同线程之间的通信,只能声明静态变量。
实现Runnable接口:
1.每个run方法可以同时让N个线程使用。
2.可以不用声明静态变量。只要保证资源和锁的同步即可。
3.可以满足更复杂的业务需求。
4.当数据量变大,业务更复杂时,配合Lock使用,更灵活。