线程是程序内部的一条执行路径
一个进程,同一时间并行多个线程,多线程
线程作为调度和执行的单位,每个线程拥有独立的运行栈和程序计数器
存在安全问题
一个java应用程序,至少有三个线程:main()主线程,
方式一
继承于Thread类
步骤:
//例:遍历100以内的所有偶数
//1.创建一个继承于Thread类的子类
public class MyThread extends Thread{
//2.重写Thread类的run()
@Override
public void run() {
for (int i = 0; i <=1000 ; i++) {
if(i%2==0){
System.out.println(Thread.currentThread().getName()+":"+i);
}
}
}
}
class ThreadTest {
public static void main(String[] args) {
//3.创建Thread类的子类的对象
MyThread myThread= new MyThread();
//4.通过此对象调用start()①启动当前线程②调用当前线程的run()
myThread.start();
// 如下操作任然是在main()线程执行的
for (int i = 0; i <=1000 ; i++) {
if(i%2!=0){
// Thread.currentThread().getName()获取线程名
System.out.println(Thread.currentThread().getName()+":"+i);
}
}
}
}
方式二
实现Runnable接口
步骤:
创建一个实现了Runnable接口的类
实现类中实现Runnable中的抽象方法:run()
创建实现类的对象
将此对象作为参数传递到Thread类的构造器中,创建Thread类的对象
通过Thread类的对象调用start()
//1. 创建一个实现了Runnable接口的类
class MIThread implements Runnable{
// 2. 实现类中实现Runnable中的抽象方法:run()
@Override
public void run() {
for (int i = 0; i < 100; i++) {
if(i%2==0){
System.out.println(Thread.currentThread().getName()+":"+i);
}
}
}
}
class ThreadTes{
public static void main(String[] args) {
// 3. 创建实现类的对象
MIThread mi= new MIThread() ;
// 4. 将此对象作为参数传递到Thread类的构造器中,创建Thread类的对象
Thread t1=new Thread(mi);
// 5. 通过Thread类的对象调用start(),启动当前线程,调用当前线程的run方法,底层是Thread含有Runnable类型参数的构造器
t1.start();
// 再启动一个线程
Thread t2=new Thread(mi);
t2.start();
}
}
比较两种创建方式
开发中优先选择,实现Runnable接口的方式
原因:
联系: public class Thread implements Runnable
相同点:两种方式都需要重写run() 将线程 要执行的逻辑声明在run()中;
优先级
NORM_PRIORITY : 5
获取和设置当前线程的优先级
高优先级的线程要抢占低优先级线程的CPU执行权,只是从概率上讲,高优先级有很高概率会执行,但并不意味着高优先级的线程执行完,低优先级的才执行;
新建:Thread类或子类对象被声明创建时
就绪:新建的线程被start()后,获取了其他所有的资源,只是没分配到CPU资源
运行:获取CPU资源,执行
阻塞:某种特殊情况下,让出CPU并临时终止自己的执行
死亡:完成它的全部工作或线程提前被强制性的终止,异常导致结束;
状态图
原文:https://www.cnblogs.com/codehan/p/14630133.html