一、并发与并行
并发:处理器不停的切换有操作的线程。
并行:多个处理器同时执行有操作线程。
二、启动线程
无论是A,B哪种方式实现多线程,都需要通过Thread.start方法启动线程。
A、Thread
自定义类继承Thread
public class MyThread extends Thread { private String name; public MyThread(String name) { this.name = name; } public void run(){ for (int i = 0; i < 1000; i++) { System.out.print("我是Thread子线程"+this.name+" "); } }
}
public static void main(String[] args) { Thread t = new MyThread("A"); t.start(); Thread t1 = new MyThread("B"); t1.start(); }
B、Runnable
自定义类实现Runnable接口
public class MyThread implements Runnable{ private String name; public MyThread(String name) { this.name = name; } @Override public void run(){ for (int i = 0; i < 1000; i++) { System.out.print("我是Thread子线程"+this.name+" "); } } }
public static void main(String[] args) { Thread t1 = new Thread(new MyThread("A")); t1.start(); Thread t2 = new Thread(new MyThread("B")); t2.start(); }
三、多线程取钱问题
存在多次取钱,账号余额不减的情况
/** * ATM对象 */ public class AtmThread extends Thread { Account account; long amount; public AtmThread(Account account, long amount) { this.account = account; this.amount = amount; } public void run() { System.out.println(); System.out.println(this.getName()+"开始取钱("+this.amount+")->"); System.out.println(this.getName()+"查询余额("+this.account.balance+")->"); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } if (this.account.balance < this.amount) { System.out.println("余额不足"); return; } this.account.setBalance(this.account.balance-this.amount); System.out.println(this.getName()+"结束取钱,余额:"+this.account.balance); } }
/** * 账户 */ public class Account { /** * 余额 */ long balance; public Account(long balance) { this.balance = balance; } public long getBalance() { return balance; } public void setBalance(long balance) { this.balance = balance; } }
public static void main(String[] args) { Account account = new Account(1000); /** * 取5次钱 */ for (int i = 0; i < 5; i++) { new AtmThread(account, 600).start(); } }
Thread-0开始取钱(600)-> Thread-3开始取钱(600)-> Thread-3查询余额(1000)-> Thread-0查询余额(1000)-> Thread-4开始取钱(600)-> Thread-4查询余额(1000)-> Thread-1开始取钱(600)-> Thread-1查询余额(1000)-> Thread-2开始取钱(600)-> Thread-2查询余额(1000)-> Thread-3结束取钱,余额:400 余额不足 Thread-0结束取钱,余额:400 Thread-1结束取钱,余额:400 余额不足
解决上面问题,使用synchronized关键字。代码修改如下:将账号对象加锁处理。
运行结果:
Thread-0开始取钱(600)-> Thread-0查询余额(1000)-> Thread-0等待中。。。。。。 Thread-0结束取钱,余额:400 Thread-4开始取钱(600)-> Thread-4查询余额(400)-> Thread-4等待中。。。。。。 Thread-4余额不足 Thread-3开始取钱(600)-> Thread-3查询余额(400)-> Thread-3等待中。。。。。。 Thread-3余额不足 Thread-2开始取钱(600)-> Thread-2查询余额(400)-> Thread-2等待中。。。。。。 Thread-2余额不足 Thread-1开始取钱(600)-> Thread-1查询余额(400)-> Thread-1等待中。。。。。。 Thread-1余额不足
四、wait set线程休息室
线程执行wait方法后,都会进入到wait set中,直到有notify,notifyAll,interrupt唤醒该线程。