进程与线程、synchronized关键字

目录

进程与线程

线程的生命周期

线程的代码实现

Thread类的使用

Runnable接口

Callable接口(返值)

线程安全性

同步方法

同步块


进程与线程

进程 --- 是一种“自包容”的应用程序,拥有自己的独立内存地址空间。

线程 --- 是在进程内部的再次划分,一个进程可以包含多个线程,这些线程是共享进程的内存地址空间。

我们的操作系统在同时运行多个程序,每一个程序就是一个进程;一个程序也可以同时完成多个执行路径,每一个执行路径就是一个线程。(GC就是在JVM中的一个线程,我们写的程序从main开始到main结束,也是JVM中的一个线程。)

多线程的同时执行,并不是绝对意义的同时。而是由CPU在多个线程之间进行来回的切换,只是它切换的速度很快,我们感觉不到它的停顿,所以认为是在同时执行。

线程的生命周期

线程的生命周期一共是5个状态

新建状态 --- new出来一个线程对象

就绪状态 --- 启动线程,但是在线程执行自己的内部代码之间。(在启动(start)和 运行(run)之间)

运行状态 --- 线程执行自己内部的代码

中断状态 --- 发生在运行过程中,这个线程由于某种原因没有被CPU执行。中断状态又有多个原因照成:由于线程优先级的原因没有抢到CPU;我们也可以让某个线程主动休眠(sleep);线程也有主动退出和换回的行为;线程在执行输入或输出的时候进入阻塞状态。

死亡状态 --- 线程执行完自己的内部代码,然后停下来开始回收自己的资源,进入自毁。

线程的代码实现

在JDK当中有1个类和两个接口用来进行多线程编程的:Thread, Runnable,Callable。其中Callable是在JDK1.5之后提出来增加Runnable的能力的。

Thread类的使用

1、我们可以通过继承Thread,然后重写它当中的run()方法来实现我们自己的线程类。 run()方法,我们可以把它想象成是这个线程的主方法。

2、在另一个线程当中,我们产生它的对象,然后调用它的start()。 注意 如果我们直接调用run(),不会报错。但相当于在做普通的方法调用,这个时候并没有启动一个新的线程。调用start()方法,才会启动新线程,并在新线程中执行run()当中的代码。

3、Thread类常用方法 sleep() --- 静态方法,用来让当前线程进入休眠状态。参数是毫秒数。一旦休眠时间到了,那么该线程会重新参与CPU的竞争。

setName() getName() --- 非静态方法,给线程对象设置名字或获取名字

setPriority() getPriority() --- 非静态方法,给线程设置优先级。总共1-10,默认为5。优先级高的不是一定比优先级低的先执行,只是它获取到CPU的几率更大而已。

Runnable接口

如果一个类已经有一个父类了,又想同时作为线程类,由于Java是单继承的,所以它不可能再同时继承Thread类了。所以,又提供了Runnable接口。

1、书写一个线程类实现Runnable接口,重写run()方法;

2、在开启它的线程中,把这个Runnable的实现类对象,传给一个Thread对象(在构造方法进行传参),然后调用Thread对象的start()。

Callable接口(返值)

无论是继承Thread的方式,还是实现Runnable的方式,都需要重写run()方法。但是run()在设计之初有两个弱点:

1、run()没有返回;

2、run()都不能抛异常。

所以在JDK1.5的时候提出了新的Callable接口,该接口的call()方法,可以有返回,也可以抛异常。

1、定义Callable的实现类,然后重写call方法。可以通过Callable的泛型,指定call()的返回类型;

2、在主线程中产生一个FutureTask对象,传入Callable实现类对象;

3、然后再new 出一个Thread对象,传入FutureTask对象;

4、调用Thread的start()方法,执行线程;执行完以后,调用FutureTask对象的get方法获取子线程返回来的数据。

线程安全性

线程安全性发生的时机:当多个线程同时操作统一“资源对象”的时候,才有可能会发生线程安全问题。

解决方案:

线程同步。我们可以在资源对象身上加一把锁(同步锁),然后让一个线程先执行,如果他没有执行完,别的线程只能进入等待。当它执行完了以后,会放开资源,然后下一个线程才进入执行。--- synchronized关键字

同步方法

当多个线程调用同一个资源对象的方法的时候,为了解决线程安全,我们给这个方法添加一个“synchronized”修饰符,让这个方法称为“同步方法”。

成为同步方法之后的效果是:当一个线程执行这个方法的时候,别的线程只能等着,直到这个方法被该线程执行结束。然后下一个线程再去执行,一个一个来。

注意: 此时synchronized关键字是加在资源类的方法身上。

同步块

当多个线程访问统一资源对象的时候,我们不在资源对象身上加同步,而是让线程内的调用处进行选择是否加同步锁进行调用。如果要加,那么就书写“同步块”。

    synchronized(资源对象){
        资源对象.行为1();
        资源对象.行为2();
    }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值