如果同时运行多个任务,则所有的系统资源将是共享的,被所有线程所公用,但是程序处理需要CPU资源
实现方式
1、继承Thread类
2、实现Runnable接口(因为java单继承,Thread有限制)
注意: 如果直接调用run()方法,则和传统一样按顺序执行,只有调用start(),才是真正的启动了线程,可以并发执行
如果要想启动线程则肯定依靠Thread类
问题1:为什么不调用run方法,而调用start方法。
因为源码中start方法中。核心是调用private native void start0()
方法。native关键字就是java程序调用本机的操作系统的函数完成特点的功能
证明如果要实现多线程,则肯定需要操作系统的支持,因为多线程操作牵扯到一个抢占CPU的情况
使用Runnable接口
Thread t1 = new Thread(new runnableImpl())
t1.start()
Thread类和Runnable接口的联系和区别
联系:Thread类也是实现Runnable接口的
区别:使用Thread类在操作多线程的时候无法达到资源共享的目的,而使用Runnable接口实现的多线程操作可以实现资源共享
示例代码:
public class MyThread extends Thread {
private int titck = 5;
@Override
public void run() {
for (int i= 0;i 0) {
System.out.println("卖票titck"+(titck--));
}
}
}
}
public class MyRunnable implements Runnable {
private int titck = 5;
@Override
public void run() {
for (int i= 0;i 0) {
System.out.println("卖票titck"+(titck--));
}
}
}
}
实现Runnable接口比继承Thread类有如下的优点
1、适合多个相同程序代码的线程去处理同一资源
2、避免由于单继承局限的影响
3、增强程序的健壮性,代码能够被多个线程共享,代码与数据是独立的
线程的状态
多线程在操作中也是有一个固定的操作状态的
- 创建状态:准备好了一个多线程的对象:Thread t = new Thread()
- 就绪状态:调用了start()方法,等待CPU进行调度
- 运行状态:执行run()方法
- 阻塞状态:暂时停止执行,可能将资源交给其他线程使用
- 终止状态:线程全部执行完,不再使用了
示意图:
注意:并不是调用了start()方法就马上运行,需要等待CPU资源调度
========================================================
多线程2-常用操作方法
Java程序运行时启动了多少个线程
答:至少启动了两个线程,一个主线程Main,一个垃圾回收线程GC。因为Java本身具有垃圾收集机制
t.isAlive():线程是否正在运行
t.join():线程强制运行,获取CPU资源运行,其他线程无法运行,必须等待此线程完成之后才可以继续执行
Thead.sleep(500):线程休眠500毫秒
t.interrupt():线程中断其运行状态,要注意中断后return操作,否则还是会跑完run方法。如果线程运行完了,中断就没意思了
t.setDaemon(true):设置线程在后台运行
线程的优先级
有三个优先级,优先级越高越有可能先执行
t.setPriority(Thred.MAX_PRIORITY)
t.setPriority(Thred.NORM_PRIORITY)
t.setPriority(Thred.MIN_PRIORITY)
线程礼让:Thread.currentThead().yield()
将一个线程的操作暂时让给其他线程执行
Object类中,wait(),notify(),notifyAll()唤醒方法
用法:在类中super.wait(),super.notify()
notify(),notifyAll()区别:一般来说,所有等待的线程会按照顺序进行排列,如果现在使用notify()方法的,则会唤醒第一个等待的线程执行,如果使用notifyAll()方法,则会唤醒所有等待的线程,那个线程的优先级高,那个线程就可能先执行
========================================================
线程生命周期
suspend():暂时挂起线程
resume():恢复挂起的线程
stop():停止线程
因为以上三个方法都会产生死锁问题,所有已不建议使用
示意图:
new Thread()–start()–>运行–sleep()/wait()–>暂停
线程停止运行只能run方法结束
可以设置标志位
示例代码
public class ThreadLife implements Runnable {
//设置标志位
private boolean flag = true;
@Override
public void run() {
int i = 1;
while (flag){
System.out.println(i++);
}
}
public void stop(){
this.flag = false;
}
}
class ThreadLifeDemo{
public static void main(String[] args){
ThreadLife threadLife = new ThreadLife();
new Thread(threadLife).start();
try {
Thread.sleep(30);
} catch (InterruptedException e) {
e.printStackTrace();
}
threadLife.stop();
}
}