# 多线程
# 线程创建
# 继承 Thread 类
package com.imooc.thread;
class MyThread extends Thread {
public void run() {
System.out.println("该线程正在执行");
}
}
public class ThreadTest {
public static void main(String[] args) {
MyThread myThread = new MyThread();
myThread.start();
}
}
# 实现 Runnable 接口
- 只有一个 run()方法
- Runnable 是 Java 中用以实现线程的接口
- 任何实现线程功能的类都必须实现该接口
为什么实现 Runnable 接口?
- Java 不支持多继承
- 不打算重写 Thread 类的其他方法
package com.imooc.runnable;
class PrintRunnable implements Runnable {
public void run() {
System.out.println(Thread.currentThread().getName()+"正在运行!");
}
}
public class Test {
public static void main(String[] args) {
PrintRunnable pr = new PrintRunnable();
Thread t1 = new Thread(pr);
t1.start();
}
}
# Thread 常用方法
public void run() // 线程相关的代码写在该方法中
public void start() // 启动线程的方法
public static void sleep(m) // 线程休眠m毫秒的方法
public void join() // 优先执行调用join()方法的线程 抢占资源
# 线程的生命周期
- 新建(New)
- 可运行(Runnable)
- 正在运行(Running)
- 阻塞(Blocked)
- 终止(Dead)
# sleep()方法
在指定的毫秒数内让正在执行的线程休眠
class PrintRunnable implements Runnable {
@Override
public void run() {
int i = 1;
while (i<=10) {
System.out.println(Thread.currentThread().getName() + "正在运行" + (i++));
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
# join()方法
join() 优先执行,其他线程等待调用该方法的线程结束后才能执行
join(long millis) 优先执行,其他线程等待该线程终止的最长时间为 millis 毫秒,然后可以执行
class PrintRunnable implements Runnable {
@Override
public void run() {
for(int i=1;i<=20;i++)
System.out.println(Thread.currentThread().getName() + "正在运行" + i + "次");
}
}
public class Test {
public static void main(String[] args) throws InterruptedException {
PrintRunnable pr = new PrintRunnable();
Thread t1 = new Thread(pr);
t1.start();
t1.join();
for(int i=1;i<=20;i++)
System.out.println("主线程运行第"+i+"次");
}
}
# 线程的优先级
- Java 为线程类提供了 10 个优先级
- 优先级可以用整数 1-10 表示,超过范围会抛出异常
- 主线程默认优先级为 5
# 优先级常量
- MAX_PRIORITY 线程最高优先级 10
- MIN_PRIORITY 线程最低优先级 1
- NORM_PRIORITY 线程的默认优先级 5
# 优先级方法
- getPriority() 获取线程优先级
- setPriority(int newPriority) 设置线程优先级
class PrintRunnable implements Runnable {
@Override
public void run() {
for(int i=1;i<=10;i++)
System.out.println(Thread.currentThread().getName() + "正在运行" + i + "次");
}
}
public class Test {
public static void main(String[] args) throws InterruptedException {
// 获取主线程的优先级
int mainPriority = Thread.currentThread().getPriority();
System.out.println("主线程的优先级为" + mainPriority);
// 自定义线程
PrintRunnable pr = new PrintRunnable();
Thread t1 = new Thread(pr);
// 设置优先级
// t1.setPriority(10);
t1.setPriority(Thread.MAX_PRIORITY);
t1.start();
System.out.println("线程1的优先级为" + t1.getPriority());
}
}
# 线程同步
# 多线程运行问题
- 各个线程通过竞争 CPU 时间而获得运行机会
- 各线程什么时候得到 CPU 时间,占用多久,是不可预测的
- 一个正在运行着的线程在什么地方被暂停是不确定的
# 银行存取款问题
- 为了保证在存款或取款的时候,不允许其他线程对账户余额进行操作
- 需要对 Bank 对象进行锁定
- 使用关键字 synchronized 实现
# 同步
- synchronized 关键字用在
- 成员方法
- 静态方法
- 语句块
// 方法不允许被打断(原子化)
public synchronized void saveAccount()
public static synchronized void saveAccount()
// 某个对象不允许其他线程访问(加锁)
synchronized(obj) {}
# 线程间通信
# 方法
- wait()方法:中断方法的执行,使线程等待(阻塞)
- notify()方法:唤醒处于等待的某一个线程
- notifyAll()方法:唤醒所有处于等待的线程
# 生产消费问题
public class Queue {
private int n;
boolean flag = false;
public synchronized int get() throws InterruptedException {
if (!flag) {
wait();
}
System.out.println("消费:" + n);
flag = false; // 消费完毕
notifyAll();
return n;
}
public synchronized void set(int n) throws InterruptedException {
if(flag) {
wait();
}
System.out.println("生产:" + n);
this.n = n;
flag=true; // 生产完毕
notifyAll();
}
}