一、多线程概念

多线程是指一个进程中,同时运行多个线程,多线程可以协作完成进程的工作,其目的是更好的利用CPU资源。

二、程序

程序是一个静态概念,是一个可执行的文件。

三、进程

执行中的程序叫做进程,是动态的执行过程。一个进程中可有多个线程。当开启一个进程,磁盘为其划分相应的存储空间,是程序运行资源分配的最小单位。

四、线程

线程是一个进程中的各个可执行单元,他们共享相应进程的资源,是cpu调度的最小单位,线程又被称为轻量级进程,必须依附于进程存在。

五、线程的实现步骤

线程的实现有两种方式:继承自Thread类和实现Runnable接口(使用较多)。

1、继承自Thread类步骤

(1)定义类,继承自Tread类;
(2)重写Thread类的run()方法;
(3)创建定义的类的对象;
(4)通过创建的对象调用strat()方法。

2、实现Runnable接口步骤(使用较多)

(1)定义类实现Runnable接口;
(2)重写Runnable的run()方法;
(3)创建定义的类的对象r;
(4)创建Thread类的对象t,创建t时,将r作为参数通过构造器传入t,绑定线程;
(5)线程t调用start()方法启动线程。

3、Thread类的sleep()方法

sleep()方法:让线程休眠,构造参数为休眠时间,单位为毫秒。
属于静态方法,可使用类名调用,也可以通过对象调用。

4、Thread类的currentThread()

静态方法,从属于类,获取当前线程。

5、Thread类的getName()和setName()方法

获取线程的名称,属于成员方法,需要通过对象调用。
getName():获取线程的名字
setName():设置线程的名字

六、设置线程的优先级

成员方法:setPriority()
优先级:1—10;优先级越来越高。只是增加CUP调度的概率,并不一定就会先调用。
优先级默认值为5,数字越大,优先级越高。(10级最高,1级最低)
常量:MAX_PRIORITY(10级)、Min_PRIORITY(1级)、NORM_PRIORITY(5级)

七、线程的生命周期中的状态

1、新生状态

创建一个线程对象后,该线程处于新生状态。

2、就绪状态

创建好的线程对象调用strat()方法后进入就绪状态,等待CPU的调度。
线程进入就绪状态的四种原因:
(1)线程调用strat()方法后,进入就绪状态;
(2)线程解除阻塞状态后,重新进入就绪状态;
(3)正在执行的线程调用yield()方法后,直接使线程进入就绪状态;
(4)线程执行时,JVM虚拟机将CPU资源切换到其他线程。

3、运行状态

线程对象被CPU调度后,执行自己的run()方法,叫做线程的运行状态。直到调用其他方法而终止,或因等待资源而阻塞,或因完成任务而死亡。

4、阻塞状态

阻塞状态是指:暂停线程的执行以等待某个条件的达成而产生的状态。
产生线程阻塞的原因:
(1)执行sleep()而进行休眠,线程会阻塞,直到指定时间结束,线程重新进入就绪状态;
(2)执行wait()方法:直接使线程进入阻塞状态,通过执行notify()方法唤醒,重新进入就绪状态;
(3)线程运行时其他某些操作可能引起阻塞线程使得线程进入阻塞状态;
(4)join()线程联合:当某个线程需要等待另一个线程执行结束后,才继续执行,使用join()方法,会造成线程阻塞。

5、死亡状态

是线程生命周期的走后一个阶段。
产生的原因:
(1)线程正常执行完run()方法中的代码死亡;
(2)被强制终止:通过stop()或者destroy()方法(已废弃)。

八、普通线程和守护线程

1、普通线程

一般用户线程,用于执行业务逻辑的线程叫做普通线程。

2、守护线程

执行的是支持(伴随)业务逻辑的线程,比如gc线程等后台线程叫做守护线程。
随着普通线程的结束,正在执行的守护线程也随之结束。
举例:银行的职员做账户相关工作是普通线程,银行的清洁阿姨就是守护线程。
线程通过调用setDaemon(true)方法可以设置为守护线程。

九、同步线程

1、线程同步:由于同一进程的多个线程共享同一块存储空间,在带来方便的同时,也带来了访问冲突的问题。
2、解决这种问题的方法是将关键字私有化(private),然后通过方法来访问这个属性,并使用synchronuzed修饰方法或者代码,保证该属性同一时间只允许一条线程访问。
3、同步方法:用synchronized修饰的方法,所属调用该方法的对象,使只有这一个对象在此事件操作。
4、同步块:使用synchronized修饰的语句块,只锁住需要锁的对象,用起来更灵活,多使用这种。
5、对象锁:某个对象执行同步方法或者同步块时锁住该对象,阻止其他线程访问。
每个对象对应一个对象锁,执行同步代码时,自动先获取对象锁,执行完后自动释放对象锁。
注意:明确需要锁住的对象,才能正确有效的执行同步代码的功能。

十、启动一个main方法,只输出“hello word”,会启动几个线程?

5个线程,分别是:main、Reference Handler、Finalizer、Singal Dispatcher、Attach Listener;
代码如下:

image.png