何为进程?
进程是程序的一次执行过程,是系统运行程序的基本单位,因此进程是动态的。系统运行一个程序即是一个进程从创建,运行到消亡的过程。如下图所示,在 windows 中通过查看任务管理器的方式,我们就可以清楚看到 window 当前运行的进程(.exe文件的运行)。
何为线程?
线程与进程相似,但线程是一个比进程更小的执行单位。一个进程在其执行的过程中可以产生多个线程。与进程不同的是同类的多个线程共享同一块内存空间和一组系统资源,所以系统在产生一个线程,或是在各个线程之间作切换工作时,负担要比进程小得多,也正因为如此,线程也被称为轻量级进程。
何为多线程?
多线程就是多个线程同时运行或交替运行。单核CPU的话是顺序执行,也就是交替运行。多核CPU的话,因为每个CPU有自己的运算器,所以在多个CPU中可以同时运行。
使用线程常见的方式
①继承Thread类
②实现Runnable接口
例子
两个人AB通过一个账户A在柜台取钱和B在ATM机取钱!
程序分析:
钱的数量要设置成一个静态的变量,两个人要取的同一个对象值。
(一)创建一个Bank类
public class Bank {
// 假设一个账户有1000块钱
static double money = 1000;
// 柜台Counter取钱的方法
private void Counter(double money) {
Bank.money -= money;
System.out.println("柜台取钱" + money + "元,还剩" + Bank.money + "元!");
}
// ATM取钱的方法
private void ATM(double money) {
Bank.money -= money;
System.out.println("ATM取钱" + money + "元,还剩" + Bank.money + "元!");
}
//提供一个对外取款途径,防止直接调取方法同时取款时,并发余额显示错误
public synchronized void outMoney(double money, String mode) throws Exception{
if(money > Bank.money){
//校验余额是否充足
throw new Exception("取款金额"+money+",余额只剩"+Bank.money+",取款失败");
}
if(Objects.equals(mode, "ATM")){
ATM(money);
} else {
Counter(money);
}
}
}
(二)创建一个PersonA类
public class PersonA extends Thread {
Bank bank;
String mode;
public PersonA(Bank bank, String mode) {
this.mode = mode;
this.bank = bank;
}
public void run (){
while(bank.money >= 100){
try {
bank.outMoney(100, mode);
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
(三)创建一个PersonB类
public class PersonB extends Thread {
Bank bank;
String mode;
public PersonB(Bank bank, String mode) {
this.bank = bank;
this.mode = mode;
}
public void run() {
while (bank.money >= 200) {
try {
bank.outMoney(200, mode);
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
(四)创建主方法的调用类
public class MainClass {
public static void main(String[] args) {
Bank bank = new Bank();
// 实例化两个人,传入同一个银行的对象
PersonA a = new PersonA(bank, "Counter");
PersonB b = new PersonB(bank, "ATM");
a.start();
b.start();
}
}
运行结果: