文章目录
什么是线程
一个进程包含多个线程
线程的创建
创建一个Thread
类,或者一个Thread
子类的对象
Thread
是一个线程类,位于java.lang
包下面,常用构造方法如下
方法 | 说明 |
---|---|
Thread() | 创建一个线程对象 |
Thread(String name) | 创建一个具有指定名称的线程对象 |
Thread(Runnable target) | 创建一个基于Runnale接口实现类的线程对象 |
Thread(Runnable target, Striing name) | 创建一个基于Runnable接口实现类,并且具有指定名称的线程对象 |
Thread
类的常用方法
方法 | 说明 |
---|---|
public void run() | 线程相关的代码写在该方法中,一般需要重写 |
public void start() | 启动线程的方法 |
public static void sleep(long m) | 线程休眠m毫秒的方法 |
public void join | 优先执行调用join() 方法的线程 |
//使用Thread类实现的时候直接new一个Thread的实现类即可
package com.sinmu.Thread1;
//定义一个类实现Thread方法
class MyThread extends Thread{
//构造方法
public MyThread(String name){
super(name);
}
public void run(){
for (int i = 1; i < 11; i++) {
System.out.println(getName()+"正在运行"+i+"次");
}
}
}
public class ThreadTest{
public static void main(String[] args) {
MyThread mt1 = new MyThread("线程1");
MyThread mt2 = new MyThread("线程2");
mt1.start();
mt2.start();
}
}
创建一个runable
实现线程的创建
- 只有一个方法
run()
Runnable
是java
中用以实现线程的接口- 任何实现线程功能的类都必须实现该接口
package com.sinmu.Runnable;
//实现runnable接口
class PrintRunnable implements Runnable{
//static Thread currentThread() 返回一个当前线程对象
@Override
public void run() {
//getName是Thread类中的一个final修饰的方法,
// 因此需要使用Thread对象去调用getName
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName()+"运行"+(i+1)+"次");
}
}
}
public class Test {
public static void main(String[] args) {
PrintRunnable printRunnable = new PrintRunnable();
Thread thread = new Thread(printRunnable);
thread.start();
PrintRunnable printRunnable1 = new PrintRunnable();
Thread thread1 = new Thread(printRunnable1);
thread1.start();
}
}
为什么要实现Runnable
接口
- java不支持多继承
- 不打算重写
Thread
类的其他方法
值得注意的是:Thread
类里面的run方法其实也是调用Runnable
接口中的run
方法去实现的
线程的状态和生命周期
线程优先级
java
为线程提供了10个优先级- 优先级可以用1-10表示,超出范围会抛出异常
- 主线程默认优先级为5
- 数字越大,优先级越高
优先级常量
MAX_PRIORITY
: 线程的最高优先级10MIN_PRIORITY
: 线程的默认优先级1NORM_PRIORITY
: 线程的默认优先级5
//优先级相关的方法
package com.sinmu.priority;
/**
* 线程优先级常用方法
* int getPriority() 返回该线程的优先级
* void setPriority(int newPriority) 设置该线程的优先级
*/
class MyThread implements Runnable{
private String name;
public MyThread(){}
public MyThread(String name){
this.name = name;
}
@Override
public void run() {
for (int i = 0; i < 3; i++) {
System.out.println("线程"+name+"正在运行"+(i+1));
}
}
}
public class PriorityDemo {
public static void main(String[] args) {
//获取主线程的优先级
int priority = Thread.currentThread().getPriority();
//System.out.println("主线程的优先级: "+priority);
MyThread test1 = new MyThread("线程1");
MyThread test2 = new MyThread("线程2");
Thread thread = new Thread(test1);
Thread thread2 = new Thread(test2);
thread.setPriority(Thread.MAX_PRIORITY);
thread2.setPriority(Thread.MIN_PRIORITY);
thread.start();
thread2.start();
//System.out.println("线程1的优先级:"+thread.getPriority());
}
}
//优先执行那个线程和操作系统有关,优先级高的不一定先执行,优先级低的不一定后执行
线程的调度
多线程运行问题
- 各个线程是通过竞争CPU时间而获得运行机会的
- 各线程说明时候得到CPU时间,占用多久,是不可预测的
- 一个正在运行的线程在什么地方被赞同是不确定的
银行存取款问题
为了保证在存款或取款的时候,不允许其他线程对账户进行操作
需要将Bank对象进行锁定,使用synchronized
实现
synchronized
可以用在成员方法、静态方法、语句块
同步与死锁
死锁
等待处于阻塞状态
当消费等待生产,而生产等待消费的取款下会进入了一个死循环的状态,这种取款被称为死锁
方法 | 说明 |
---|---|
wait() | 中断方法的执行,使得线程等待 |
notify() | 唤醒处于等待的某一个线程,使得其结束等待 |
notifyAll() | 幻想所有处于等待的线程,使他们结束等待 |