JAVA进阶知识学习-day06

一、 线程

1.1 多线程原理:程序启动运行main时候,java虚拟机启动一个进程,主线程main在main()调用时候被创建。随着调用新线程对象的start方法,另外一个新的线程也启动了,这样,整个应用就在多线程下运行。

1.2 多线程运行图解:

        

1.3 Thread类

1.3.1 Thread类的构造方法:

public Thread() :分配一个新的线程对象。 

public Thread(String name) :分配一个指定名字的新的线程对象。 

public Thread(Runnable target) :分配一个带有指定目标新的线程对象。 

public Thread(Runnable target,String name) :分配一个带有指定目标新的线程对象并指定名字。

1.3.2 Thread类的常用方法:

public String getName() :获取当前线程名称。 

public void start() :导致此线程开始执行; Java虚拟机调用此线程的run方法。 

public void run() :此线程要执行的任务在此处定义代码。 

public static void sleep(long millis) :使当前正在执行的线程以指定的毫秒数暂停。 public static Thread currentThread() :返回对当前正在执行的线程对象的引用。

1.4 第二种创建线程的方式:

1.4.1 概述:采用java.lang.Runnable来创建线程,我们只需要重写run方法即可。

1.4.2 创建步骤:

1. 定义Runnable接口的实现类,并重写该接口的run()方法,该run()方法的方法体同样是该线程的线程执行体。 

2. 创建Runnable实现类的实例,并以此实例作为Thread的target来创建Thread对象,该Thread对象才是真正的线程对象。 

3. 调用线程对象的start()方法来启动线程。

1.4.3 使用举例:

        

1.5 Thread和Runnable的区别

1.5.1 实现Runnable接口比继承Thread类所具有的优势: 

1. 适合多个相同的程序代码的线程去共享同一个资源。 

2. 可以避免java中的单继承的局限性。 

3. 增加程序的健壮性,实现解耦操作,代码可以被多个线程共享,代码和线程独立。 

4. 线程池只能放入实现Runable或Callable类线程,不能直接放入继承Thread的类。

1.5.2 总结:如果一个类继承Thread,则不适合资源共享。但是如果实现了Runable接口的话,则很容易的实现资源共享,推荐使用Runable接口

1.6 匿名内部类方式实现线程的创建

1.6.1 使用线程的内匿名内部类方式,可以方便的实现每个线程执行不同的线程任务操作。也可以简化代码。

1.6.2 代码实现:

                    

二、线程安全

2.1 当我们使用多个线程访问同一资源的时候,且多个线程中对资源有写的操作,就容易出现线程安全问题。

2.2 线程同步机制,有三种方式完成同步操作:

1. 同步代码块。 

2. 同步方法。 

3. 锁机制。

2.3 同步代码块:synchronized 关键字可以用于方法中的某个区块中,表示只对这个区块的资源实行互斥访问。

2.3.1 格式: synchronized(同步锁){ 需要同步操作的代码 }

2.3.2 对象的同步锁只是一个概念,可以想象为在对象上标记了一个锁:

1. 锁对象可以是任意类型。 

2. 多个线程对象要使用同一把锁。

2.3.3 注意事项:在任何时候,最多允许一个线程拥有同步锁,谁拿到锁就进入代码块,其他的线程只能在外等着 。

2.3.4 代码演示:

        

2.4 同步方法:使用synchronized修饰的方法,就叫做同步方法,保证A线程执行该方法的时候,其他线程只能在方法外等着。

2.4.1 格式: public synchronized void method(){ 可能会产生线程安全问题的代码 }

2.5 Lock锁:java.util.concurrent.locks.Lock机制提供了比synchronized代码块和synchronized方法更广泛的锁定操作, 同步代码块/同步方法具有的功能Lock都有,除此之外更强大,更体现面向对象。

2.5.1 Lock锁常用方法: 

public void lock() :加同步锁。 

public void unlock() :释放同步锁。

2.5.2 Lock锁使用演示:

        

三、线程状态

3.1 当线程被创建并启动以后,它既不是一启动就进入了执行状态,也不是一直处于执行状态。在线程的生命周期中, 一共有6种线程状态

3.2 各个线程状态发生的条件:

        

3.3 Timed Waiting(计时等待)

3.3.1 当我们调用了sleep方法之后,当前执行的线程就进入到“休眠状态”,其实就是所谓的Timed Waiting(计时等待)

3.3.2 使用演示: Thread.sleep(1000);

3.3.3 注意事项: 

1. 进入TIMED_WAITING状态的一种常见情形是调用的 sleep 方法,单独的线程也可以调用,不一定非要有协作关系。 

2. 为了让其他线程有机会执行,可以将Thread.sleep()的调用放线程run()之内。这样才能保证该线程执行过程中会睡眠

3. sleep与锁无关,线程睡眠到期自动苏醒,并返回到Runnable(可运行)状态。

3.4 BLOCKED(锁阻塞)

3.4.1 线程A与线程B代码中使用同一锁,如果线程A获取到锁,线程A进入到Runnable状态,那么线程B就进入到Blocked锁阻塞状态。

3.5 Waiting(无限等待)

3.5.1 当多个线程协作时,比如A,B线程,如果A线程在Runnable(可运行)状态中调用了wait()方法那么A线程就进入了Waiting(无限等待)状态,同时失去了同步锁。假如这个时候B线程获取到了同步锁,在运行状态中调用了notify()方法,那么就会将无限等待的A线程唤醒。注意是唤醒,如果获取到锁对象,那么A线程唤醒后就进入 Runnable(可运行)状态;如果没有获取锁对象,那么就进入到Blocked(锁阻塞状态)。

3.5.2  Waiting 线程状态图:

        

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小陈工

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值