java 多线程 ONE

参考博客:

Java线程的6种状态及切换(透彻讲解)

Java中一个线程只有六个状态。至于阻塞、可运行、挂起状态都是人们为了便于理解,自己加上去的。

Java中的多线程你只要看这一篇就够了

关于NIO,剩下的都是关于网络编程的,这方面没接触过,所以先放下,接下来学习多线程

关于多线程,想了想什么是线程,什么是进程,什么是线程安全,没想出来。所以第一步还是补充线程相关的概念

A 进程:

    狭义上说,进程就是一段程序执行的过程

    广义上讲:进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动

    进程有三个状态:就绪,运行和阻塞。就绪状态就是已经获取了CPU的所有资源,只要处理器分配资源就可以马上执行。运行状态是获取了处理器分配的资源,程序开始执行。阻塞是当程序条件不够的时候,需要等待条件满足才能执行。

    进程中的文本区域就是代码区,也就是程序

B 线程:

    通常在一个进程中有多个线程,一个进程中至少有一个线程。线程可利用进程所拥有的资源,在引入线程的操作系统中,通常把进程作为分配资源的基本单位,而把线程作为独立运行和独立调度的基本单位,由于线程比进程小,基本上不拥有系统资源,故对它的调度所付出的开销小。

C:多线程:指的是这个程序运行时产生了不止一个线程

    多线程是为了同步完成任务,不是为了提高运行效率,而是为了提高资源使用效率来提高系统的效率。

一个进程崩溃的时候,由于有保护机制,所以不会对其他的进程有影响,但如果一线程死掉了,那么就等于整个进程死掉了。所以多进程的程序比多线程的程序健壮,但进程切换的时候,资源消耗较大,效率差一些。但对一些要求同时进行并且又要共享某些变量的并发操作的时候,只能用线程。

D:并行:

    多个CPU实例或多台机器同时执行一段处理逻辑,真正的同时

E:并发

    采用CPU调度算法,让用户看上去同时执行,实际上并不是同时执行。

F: 线程安全

    经常用来描绘一段代码。指在并发的情况之下,该代码经过多线程使用,线程的调度顺序不影响任何结果。这个时候使用多线程,我们只需要关注系统的内存,cpu是不是够用即可。反过来,线程不安全就意味着线程的调度顺序会影响最终结果

G:同步:

    Java中的同步指的是通过人为的控制和调度,保证共享资源的多线程访问成为线程安全,来保证结果的准确。如代码简单加入@synchronized关键字。在保证结果准确的同时,提高性能,才是优秀的程序。线程安全的优先级高于性能。

线程的状态

public enum State {
        初始:新创建了一个线程对象,但还没有调用start()方法。
        NEW,

        运行:Java线程中将就绪(ready)和运行中(running)两种状态笼统的称为“运行”。
        线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。该状态的线程位于可运行 
        线程池中,等待被线程调度选中,获取CPU的使用权,此时处于就绪状态(ready)。就绪状态的线程 
        在获得CPU时间片后变为运行中状态(running)。
        RUNNABLE,

        阻塞:表示线程阻塞于锁。
        BLOCKED,

        等待:进入该状态的线程需要等待其他线程做出一些特定动作(通知或中断)。
        WAITING,

        超时等待:该状态不同于WAITING,它可以在指定的时间后自行返回。
        TIMED_WAITING,

        终止:表示该线程已经执行完毕。
        TERMINATED;
    }

1.初始状态:实现Runnable接口和继承Thread可以得到一个线程类,new一个实例出来,线程就进入了初始状态。

2.1 就绪状态:就绪状只是说你有资格运行,调度程序没有挑选你,你永远是就绪状态

                        调用线程的start()方法,线程进入就绪状态

                        当前线程的seep()结束,其他线程的join()结束,等待用户输入完毕,某个线程拿到对象锁,这些线程也将进入就绪状态。

                        当前线程的时间片用完了,调用当前线程的yield()方法,当前线程进入就绪状态

                        锁池中的线程拿到对象锁以后,进入就绪状态

2.2运行中状态:

                        线程调度程序从可运行池中选择一个线程作为当前线程所处的状态,这也是线程进入运行状态的唯一方式。

3.阻塞状态:

                  阻塞状态是线程阻塞在进入synchronized关键字修饰的方法或代码块(获取锁)时的状态。

4等待:

          处于这种状态的线程不会被分配CPU执行时间,它们要等待被显式地唤醒,否则会处于无限期等待的状态

5超时等待:

                处于这种状态的线程不会被分配CPU执行时间,不过无须无限期等待被其他线程显示地唤醒,在达到一定时间后它们会自动唤醒。

6终止状态:

                当线程的run()方法完成时,或者主线程的main()方法完成时,我们就认为它终止了。这个线程对象也许是活的,但是,它已经不是一个单独执行的线程。线程一旦终止了,就不能复生

                在一个终止的线程上调用start()方法,会抛出java.lang.IllegalThreadStateException异常。

synchronized, wait, notify 是任何对象都具有的同步工具

wait/notify必须存在于synchronized块中。并且,这三个关键字针对的是同一个监视器(某对象的监视器)

Java中的每个对象都有一个监视器,来监测并发代码的重入。在非多线程编码时该监视器不发挥作用,反之如果在synchronized 范围内,监视器发挥作用

多线程的内存模型:main memory(主存)、working memory(线程栈),在处理数据时,线程会把值从主存load到本地栈,完成操作后再save回去(volatile关键词的作用:每次针对该变量的操作都激发一次load and save)。

针对多线程使用的变量如果不是volatile或者final修饰的,很有可能产生不可预知的结果(另一个线程修改了这个值,但是之后在某线程看到的是修改之前的值)。其实道理上讲同一实例的同一属性本身只有一个副本。但是多线程是会缓存值的,本质上,volatile就是不去缓存,直接取值。在线程安全的情况下加volatile会牺牲性能。


 

猜你喜欢

转载自blog.csdn.net/qq_35815781/article/details/85674514