五、多线程

如果同时运行多个任务,则所有的系统资源将是共享的,被所有线程所公用,但是程序处理需要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()方法
  • 阻塞状态:暂时停止执行,可能将资源交给其他线程使用
  • 终止状态:线程全部执行完,不再使用了

示意图:

线程的状态.png

注意:并不是调用了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()–>暂停

线程生命示意图.png

线程停止运行只能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();
   }
}

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注