多线程与ThreadLocal的理解笔记

一、线程与进程的区别

进程是指一种“自包容”的运行程序,由操作系统直接管理,直接运行,有自己的地址空间,每个进程一开启都会消耗内存。

线程是进程内部单一的顺序控制流,一个进程拥有多个线程,多个线程共享一个进程的内部空间。

二、主线程

main方法一运行,就开启主线程。

主线程的特点:1、最先开始;2、最后结束;2、产生其他子线程;4、回收资源。

三、创建和启动线程

Thread thread=new Thread(继承了Thread或实现了Runnable接口的对象) //这是一种规范,在创建线程完成后都需要设置名称。 thread.setName("设置一个线程名称"); //启动线程使用start方法,而启动了之后执行的是run方法。 thread.start();

四、创建线程对象

1、继承---声明一个Thread类的子类,并覆盖run()方法。

class mythread extends Thread{
    public void run(){
        /*覆盖方法*/
    }
}

2、实现接口----声明一个实现类Runnable接口类,并实现run()方法

class mythread implements Runnable{ 
    public void run(){
        /*实现该方法*/
    } 
}

五、线程调用的start方法和run方法的区别

1、调用start方法,是启动线程,会在主线程之外,开启新的子线程。

2、调用run方法,是普通方法调用。

六、线程并发库

JDK5中增加了Doug Lea的并发库,java.util.current包。该包提供了线程的运行和生命周期的控制,及线程池的创建。

Java通过Executors类提供四个静态方法创建线程池,分别为:

newCachedTreadPool 创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。

newFixedTreadPool(★★★★★)创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。

newScheduledTreadPool 创建一个定长线程池,支持定时及周期性任务执行。

newSingleTreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO,LIFO,优先级)执行。

七、线程池的作用

1、限定线程的个数,不会导致由于线程过多而线程溢出异常(系统运行缓慢或崩溃)。

2、线程池不需要每次都去创建和销毁,节约了资源。

3、响应时间更快,提升了性能。

注:连接池与线程池原理机制基本一样。都是运用的以空间换时间的优化策略。

八、线程流程(线程的八种状态):

1、---新建(产生线程对象)

2、---就绪(调用start())

3、---执行(执行run())----以下四种状态完成后都会回到就绪状态。

    1. 休眠--调用sleep()方法(常用)

    2. 等待--调用wait()方法(常用)

    3. 挂起--调用yeld()方法(不常用)

    4. 阻塞--IO阻塞,等待用户输入内容(常用)

4、---死亡(run()执行完毕)

九、wait和sleep的区别

//当前线程休眠一秒,在执行当前线程 

Thread.sleep(1000);

sleep方法在线程类Thread中定义,wait方法在Object中定义。

wait方法只能放在同步方法或者同步块中,表示当前线程对资源进行等待。sleep方法可以放在任何位置,表示当前线程休眠。

wait方法要释放对象锁,sleep方法不会释放对象锁。

wait方法使用后,线程需要notify唤醒后才能继续执行。而sleep在休眠结束后,线程自动继续执行。

十、线程同步(线程安全):

1、当两个或两个以上的线程同时访问同一个资源时,为了避免数据混乱,只允许同一时间一个线程进行访问。

2、synchronized(声可儿来日得)关键字:第一个线程未执行完毕前,第二个线程不能访问。(放在public之后,void之前);

3、线程同步的结果:----1、数据安全 ----2、效率低下

十一、线程优先级:

当两或两个以上的线程处于就绪状态时,优先级高的线程会优先得到CPU的执行。优先级共有10级,数字越大优先级越高。默认为5级。

    • NORM_PRIORITY:值为5
    • MAX_PRIORITY:值为10
    • MIN_PRIORITY:值为1

缺省优先级为 NORM_PRIORITY

有关优先级的方法有两个:

    • final void setPriority(int newp):修改线程的当前优先级。
    • final int getPriority():返回线程的优先级。

十二、死锁

当两个线程循环依赖于对同步对象时将发生死锁。

例如:一个线程进入对象ObjA上的监视器,而另一个线程进入对象ObjB上的监视器。如果ObjA中的线程试图调用ObjB上的任何synchronized方法,就将发生死锁。

死锁很少发生,但一旦发生就很难调试。

十三、ThreadLocal(本地化线程)

1、定义

①、ThreadLocal它不是一个线程,而是线程的一个本地化对象。

②、当工作于线程的对象使用ThreadLocal维护变量时,它会为每个使用该变量的线程分配一个独立的变量副本。

③、在内存中复制线程副本,以空间换时间。

2、限制

唯一变量不能复制的,只能同步上锁。

3、接口方法

①、void set(Object value); 设置当前线程的局部变量。

②、Object get();获取当前线程的局部变量。

4、实现机制

底层通过Map集合存储每一个线程变量副本,Map中的Key对应线程对象(线程ID),value对应线程的变量副本。

5、与线程同步机制的比较

同步机制中:多个线程不能同时访问一个变量,只能依次排队访问。线程同步机制在处理多线程访问时,采用的是以时间换空间,访问串行化,对象共享化的实线思路。

ThreadLocal:它为每一个线程创建独立的变量副本,可以实现异步并且保证数据有效性,采用的是以空间换时间,访问并行化,对象独享化的实现思路。

猜你喜欢

转载自blog.csdn.net/qq_42080073/article/details/102996000