Java线程安全

本文详细解释了程序、进程、线程和携程之间的关系,介绍了线程生命周期和创建方法,包括继承Thread和实现Runnable/Callable接口。重点讲解了如何使用同步代码块和同步方法来解决线程安全问题,以及锁的概念和使用方式。
摘要由CSDN通过智能技术生成

目录

1.程序,进程,线程,携程

        四者联系:

        四者具体功能:

2.线程生命周期

3.线程创建和操作方法

 3.1继承Thread类

 3.2实现Runnable接口

3.3相比继承Thread,优先使用Runnable接口原因

3.4实现Callable接口

3.5Thread类操作方法(持续更新)

4.同步代码块和同步方法解决线程安全问题

4.1继承Thread

4.2实现Runnable接口

4.3锁是啥,怎么用

4.3.1 正常途径

4.4总结两策略


1.程序,进程,线程,携程

        四者联系:

        一个运行程序(Program)=一个进程(Process)

        一个进程可能存在多个线程(Thread) 同步或异步

        一个线程可能存在多个携程(Coroutines) 

        四者具体功能:

          Program 是静态代码

          Process 程序的实例,拥有独立地址空间

          Thread 调度和执行的最小单位,是进程中一个实体,有独立栈,但共享进程的地址空间;若进程同一时间“并行”执行,即为多线程

补充:并行 指多个CPU同时执行多个任务

           并发 指一个CPU同时执行多个任务

2.线程生命周期

3.线程创建和操作方法

作为最小执行单位,拥有Thread父类和Runnable接口,Callable接口

 3.1继承Thread类

        创建Thread子类,按需求重写run()方法 【run代表此线程执行时会做的事】

        这里的属性若为 多线程共享属性,加static修饰

        实例化Thread子类

 3.2实现Runnable接口

 这里的 多线程共享属性 可以是非静态的,因为多线程共用此接口

先实现接口,Thread构造器有 Thread(Runnable){},这样多个线程共用同一个run方法和各属性

但是以上两种方法都会出现线程抢占安全问题

3.3相比继承Thread,优先使用Runnable接口原因

(1)非静态属性也是共享数据

(2)非静态方法可直接用synchronized修饰

3.4实现Callable接口

(1)实现接口Callable,重写call()回调方法,会返回一个值,值类型由Callable泛型决定

(2)实例化上述类,利用FutureTask(Callable)构造器实例化类,最终实例化Thread(FutureTask)以创建线程

(3)特别注意

在实现Callable接口时,抛出了异常,需要我们在使用时try_catch接受异常,通常系统会提示,我们可以让系统帮我们自动生成上去

3.5Thread类操作方法(持续更新)

        sleep(millis) 此线程从运行进入阻塞状态  ;millis结束,此线程又回到就绪状态【不释放锁】

        join()  在B线程调用A.join(),使得B线程等待A执行完,B线程才能执行【源码使用wait封装,会释放当前线程同步锁】

        join(millis) 同上,只是等待一个线程有了最长时间,时间到或者提前执行完才会回到当前线程

        

        wait()线程进入阻塞状态,并释放同步锁

        notify()  将 由wait()阻塞线程中优先级最高的那个转为  就绪态

        notifyAll() 将所wait()阻塞线程全部转变为 就绪态

        getPriority()获取线程优先级

        setPriority()设置线程优先级  【优先级为1-10,默认是5;Thread.MIN_PRIORITY为1,Thread.MAN_PRIORITY为10】

        Thread.currentThread() 随时获取当前执行线程

        getName()获取当前线程名字

        setName(String)设置当前线程名字     

        run() 线程执行的具体任务

        start()让线程进入就绪状态,随时准备开始执行

        yield()该线程失去CPU,从运行态转为就绪态【不释放锁】

        stop()运行的线程死亡

        suspend()挂起线程,由执行态转为阻塞态【不释放锁】       

        resume()恢复被挂起的线程 ,由阻塞态转为就绪态

             call() 是Callable接口的回调方法,能在线程执行时执行功能,并返回一个值

4.同步代码块和同步方法解决线程安全问题

4.1继承Thread

        同步代码块——》操作共享数据的代码,只允许一个线程正在执行

           格式: synchronized{

             //  只能同时让一个线程执行的任务

                  }

注意:synchronized(同步监视器),同步监视器必须唯一,这里不能用this,会代表多个实例化对象,最好用该类的字节码

     

        同步方法格式:

如下图 必须是synchronized修饰的静态方法  ,若无static则同步监视器默认为this,线程不安全

4.2实现Runnable接口

同步代码块:

同步监视器保证唯一性,这里this代表的实现接口的对象,只有一个,也可以用其他唯一的

同步方法:

直接加synchronized修饰

4.3锁是啥,怎么用

锁-》官方名字“同步监视器”,是我们同步代码块和同步方法确定在哪个线程执行的依据

下面我们要学会释放锁

4.3.1 正常途径

同步方法,同步代码块执行结束

同步方法,同步代码块中遇到break,return 提前终止 代码执行

线程对象的wait(),使线程进入阻塞态并释放锁

4.3.2 异常途径

抛出了Error或者Exception未处理【我指的try_catch】,就导致程序异常结束,整个程序直接崩溃掉。。。

4.4总结两策略

注意同步构造器的唯一性 ,(特别注意this在继承Thread时不能用)

同步方法 在继承Thread类模式下,同步方法用static修饰,同步代码块不能用this, 这是保证同步监视器唯一性

  • 11
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值