并发编程:JAVA线程篇

目录

一.什么是并发编程

二.线程 

2.1 守护线程和用户线程

2.2 线程的生命周期

2.3 线程的三种创建方式

2.4 线程的常用方法


一.什么是并发编程

同一时间段内多个线程运行,也就是所谓的处理器"同时"处理多个任务。

"同时" :实际并不是同时处理,而是在操作系统的调度下交替执行。

二.线程 

2.1 守护线程和用户线程

在JAVA中线程分为守护线程和用户线程。

用户线程:是独立存在的,不会因为其他用户线程退出而退出。

守护线程:是依赖于用户线程,用户线程退出了,守护线程也就会退出,典型的守护线程如垃圾回收线程。

默认情况下启动的线程是用户线程,可以使用Tread.setDeamon(true)设置为守护线程;注:必须在线程启动前设置,不然会报java.lang.IllegalThreadStateException异常,启动的线程无法变成守护线程,而是用户线程。

2.2 线程的生命周期

五个阶段:新建-->就绪-->运行-->阻塞-->死亡

新建(New):当线程对象对创建后,即进入了新建状态,如:Thread t = new MyThread();

就绪(Runnable):当调用线程对象的start()方法,线程即进入就绪状态。处于就绪状态的线程,只是说明此线程已经做好了准备,随时等待CPU调度执行,并不是说执行了t.start()此线程立即就会执行;

运行(Running):当CPU开始调度处于就绪状态的线程时,此时线程才得以真正执行,即进入到运行状态。注:就绪状态是进入到运行状态的唯一入口,也就是说,线程要想进入运行状态执行,首先必须处于就绪状态中;

阻塞(Blocked):处于运行状态中的线程由于某种原因,暂时放弃对CPU的使用权,停止执行,此时进入阻塞状态,直到其进入到就绪状态,才 有机会再次被CPU调用以进入到运行状态。根据阻塞产生的原因不同,阻塞状态又可以分为三种:

        1.等待阻塞:运行状态中的线程执行wait()方法,使本线程进入到等待阻塞状态;

        2.同步阻塞:线程在获取synchronized同步锁失败(因为锁被其它线程所占用),它会进入同步阻塞状态;

        3.其他阻塞:通过调用线程的sleep()或join()或发出了I/O请求时,线程会进入到阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。

死亡(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。

2.3 线程的三种创建方式

1.通过继承Thread类:

注:需要重写Thread类里的run()方法

public class MyThread extends Thread{
    public static void main(String[] args) {
        //创建类并启动线程
        new MyThread().start();
    }
    @Override
    public void run() {
        System.out.println("业务代码");
    }
}

2.通过实现Runnable接口:

注:需要实现接口里面的run()方法并作为参数传入Thread类

public class MyRunnable implements Runnable{
    @Override
    public void run() {
        System.out.println("业务代码");
    }
    public static void main(String[] args) {
        //作为构造器参数传入Thread,实际就是将run方法带入到Thread
        Thread thread = new Thread(new MyRunnable());
        thread.start();
    }
}

3.通过Callable和FutureTask接口创建线程

注:通过调用FutureTask类的get方法得到返回值,注意:这个方法是阻塞方法,会在这等着线程执行完成

public class MyCallable implements Callable {
    @Override
    public String call()  {
        System.out.println("业务代码");
        return "我是返回值";
    }
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //将Callable类作为FutureTask的构造参数传入
        FutureTask task = new FutureTask(new MyCallable());
        Thread thread = new Thread(task);
        thread.start();
        //通过调用FutureTask类的get方法得到返回值,注意:这个方法是阻塞方法,会在这等着线程执行完成
        System.out.println(task.get());
    }
}

2.4 线程的常用方法

(1)wait:使线程让出CPU执行权,进入等待状态(注:会释放锁),在满足条件下再被唤醒。

使用前提:必须要取得这个锁对象的控制权(对象监视器)。

唤醒条件:当调用notify方法唤醒的刚好是本线程时,或者调用了notifyAll方法。注意:wait释放锁只会释放当前这把锁,即哪个对象调用了wait,就释放那个对象的锁。

(2)notify:随机唤醒一个处于等待状态的线程。

(3)notifyAll:唤醒所有处于等待状态的线程。注意:wait、notify、notifyAll必须在synchronized关键字修饰的方法或者代码块中,否则会抛出异常。

(4)sleep:使线程让出CPU执行权,进入等待状态(不释放锁),等sleep休眠结束后,才释放锁。注意:休眠期间线程如果被中断,则会抛出异常并清除中断状态。

(5)join:当正在运行的线程调用了某个线程的join方法时,调用者进入等待状态,当该线程运行完毕后调用者进入就绪(Runnable)状态。注意:当某个线程调用了join方法后,该线程会抢占到CPU资源,不会再释放,直到线程执行完毕。

(6)yield:使线程让出CPU执行权,进入就绪状态(不释放锁),只允许与改线程拥有相同优先级的线程抢占CPU。

(7)interrupt:设置中断标志位。

(8)isInterrupted:判断线程是否被中断。

(9)interrupted:判断当前中断状态。注意:调用之后中断状态将会刷新。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值