并发编程----1.并发编程线程基础

并发编程----1.并发编程线程基础

1.1 什么是线程

  (1)线程是cpu的最小执行单位
  
  (2)线程不能独立存在,运行在进程的内部
  
  (3)一个进程可以有多个线程,多个线程共享进程内部的资源
  
  (4)线程共享进程的堆和方法区,拥有自己独立的栈空间和程序计数器。堆中存放实例,方法区存放静态变量
	  和常量还有jvm加载的类,这些是线程共享的,线程的栈资源存放线程的局部变量,这些是私有的,程序计
	  数器记录线程让出cpu时候的执行地址。

1.2 线程的创建和运行

  (1)线程创建方法有四种
  	  
  	  	  1. 继承thread
  	  	  		
  	  	  2. 实现runnable
  	  
  	      3. 内部实现类
  	  
  	      4. FutureTask,实现callable方法类似于runnable
  	  
  	      5.线程池
  	      
	(2)线程的运行
	
		  1. start 方法创建一条线程并且运行,只有使用start方法才会有线程创建并且执行,只使用run不会创建
		     线程
		     
	(3)几种创建线程方法的区别
	
	 	  1. 继承方便传参,可以在子类中添加成员变量,通过set和get方式或者构造器函数进行传递,如果是runable
	 	      方式只能使用主线程中被声明为final的变量,
	 	  		
  	  	  2. 继承thread类,子类不能继承其他类,而实现接口没有这个限制
  	  
  	      3. FutureTask可以拿到任务返回的结果。

1.3 线程的通知和等待

java中Object是所有类的父类,鉴于继承机制,java把所有需要的方法都放到Object中,其中就包括wait和notify

	(1)wait()函数
		
		1. 使用:线程在一个共享变量的wait方法时,该线程会被阻塞挂起
		 
		2. 返回:只有当其他线程调用了notifyAll或者notify,或者其他线程调用了该线程的interrupt方法该线程抛出
		   InterredException返回
		
		3.特点
		
			a. 只有wait获得对象监视器才能被阻塞挂起,否则会抛出IIegalMonitorStateException
			
			b. 使用wait阻塞后当前线程会释放所获得的锁
			
	(2)wait(long timeout)函数
	
			1. 特点:线程在一个共享变量的wait方法时,该线程会被阻塞挂起,超时时返回
	
	(3)wait(long timeout,int nanos)函数
	
			1. 特点:内部调用wait(long timeout)函数,只有在nanos>0在使参数timeout递增1
			
	(4)notify()函数
	
			1. 使用:随缘唤醒一个使用wait的线程,但是该线程不会立刻执行,必须在获取对象锁后才可以返回
			
			2. 返回:只有获得对象监视器锁才能使用notify
			
	(5)notifyAll()函数
	
			1. 使用:唤醒在等待池中所有wait的线程,但是这些线程不会立刻执行,必须在获取对象锁后才可以返回
			
			2. 返回:只有获得对象监视器锁才能使用notify

1.4 等待线程终止的join方法

等待某件事完成后才能继续执行下去的方法

1.5 让线程睡眠的sleep方法

	(1)指定时间让出cpu的执行权,在这期间不参与调度,但是不释放监视器锁
	
	(2)当时间到了,线程就处于就绪的状态,参与cpu的调度
	
	(3)可以使用该线程的interrupted是该线程返回

1.6 让出cpu执行权的yield方法

让出cpu执行权然后处于就绪状态,线程调度器会从线程就绪队列中找到优先级最高的线程,或者是刚刚让出cpu执行权的线程

1.7 线程中断

线程是一种线程间协作的方式,设置线程中断标志不能直接终止该线程的执行,而是被中断的线程根据中断状态自行处理

	(1)void interrupt()方法:中断线程。当线程A运行的时候,线程B可以调用线程A的interrupt()方法来设置线程A
	    的中断标志为true并立即返回,线程A实际没有中断而继续执行。当线程A被阻塞的时候,调用会抛出InterredException
	    返回
	
	(2)boolean isInterrupted()方法:是否中断,如果是返回true,否则返回false
	
	(3)boolean interrupted()方法:是否中断,如果是返回true,否则返回false。如果线程中断清除中断标志,并且该方
		法是static,可以通过Thread类直接调用,

1.8 理解上下文切换

在单核cpu中,同一时间点中只能一个线程执行(并发),在多核cpu中,同一时间点中可以有多个线程执行(并行)
在单核cpu中,为了让用户感觉多个线程同时执行的,cpu使用**时间分片**的方法,也就是cpu给每个线程分配时间片,当该线程
执行完自己的时间片,便进入就绪状态让其他的线程占有,等待cpu的分配。这就是上下文的切换。在这个过程中,线程必须保存自己的执行现场。

1.9 线程死锁

死锁的定义:两个或者两个以上的线程,因争夺资源而出现的互相等待的情况

	(1)产生死锁的条件
			
			1. 互斥
				
				一个资源只能同时一个线程使用。其他线程的请求资源只能等待占有资源的线程释放资源。
				
			2. 请求与保持
				
				A线程请求B线程占有的资源,而A线程同时也占有B线程请求的资源,只有等待A请求到B占有的资源才能释放,
				但是B也是只有等待A释放资源才能释放占有的资源。
			
			3. 不可剥夺
			
				当线程占有资源的时候,系统不能使其释放,只能等待他自己释放
			
			4. 循环等待
				
				多个线程之间请求资源形成环状的请求
				
	(2)如何避免线程死锁
			
			* 破坏环路和请求与保持条件,也就是正确的请求锁的顺序

1.10 守护线程与用户线程

线程分为守护线程和用户线程。在jvm启动的时候,main函数所在的线程就是用户线程,垃圾回收线程就是守护线程
特点就是所有用户线程结束之后,所有的守护线程必须结束。

1.11 Threadlocal

多线程访问同一个共享变量时特别容易出现并发问题,特别是写入问题。加锁加重了使用者的负担。而ThreadLocal的出现便解决了这个问题,让线程对其访问是自己的线程变量,也就是存储在线程中变量的副本。本质上是操作线程内部ThreadLocalMap的壳。ThreadLocalMap的key为ThreadLocal的引用,value为我们设置的值

	(1)ThreadLocal的实现原理
		
	    	1. set()使用: 每个线程都有自己的ThreadLocalMap,如果是第一次使用,便会初始化ThreadLocalMap,并且将
	    	   写入信息,反之直接写入线程的ThreadLocalMap
	    	   
	    	2. get()使用: 获取当前线程的ThreadLocalMap,取得当前ThreadLocal对应的value
	    	
	    	3. remove()使用:获取线程,使用ThreadLocalMap的remove

    (2)ThreadLocal不支持继承性

			1. 子类 无法获取到父类ThreadLocal中的值。在上面的get()可以很清楚的看到,只是拿到自己的键值对

    (3)InheritableThreadLocal类
    		
    		1. 线程	中存在一个inheritableThreadLocals的变量也是ThreadLocalMap类型的存着父类的ThreadLocal

    		2. InheritableThreadLocal类继承了ThreadLocal并且重写了childValue(),getMap(),createMap()目
    		   的是通过inheritableThreadLocals获取对应的ThreadLocalMap
    		
	(4)弱引用内存泄露
			
			1. 原因:ThreadLocalMap 中的 key继承 weak reference (弱引用),也就是说当空间不够的时候,key就会被回收
			,这样可以节约内存。但是同时value 和entry 还是强引用的关系,只要这种关系不接触,value就永远不会被回收。
			
			3. 解决:ThreadLocl 每次set、get、remove 操作时,threadlocal 都会把key为null的值删除,但是这样还是无法完全
			  解决内存泄露的问题,所以需要手动remove
	
	(5)static 修饰 threadLocal:
			
			1. 
	(6)注意
			
			* 使用完改变了要及时删除,不然该变量会随着线程的存在一直存在,可能会造成线程溢出

1.12 volatile

volatile 确保更新可以通知到其他线程。当变量声明为volatile类型后,编译器运行会注意到这个变量是共享的。因此不会将该变量上的操作与其他内存操作一起重排序。volatile 变量不会被缓存在寄存器或者对其他处理器不可以见的地方。因此在读取volatile类型的变量时总会返回最新写入的值。

	(1)  volatile 与可见性 
	(2)  volatile 与有序性
	(3)  volatile 特点
		
		1. volatile和synchronized 的比较: 不加锁也不阻塞线程 所以是比synchronized 更轻量级的同步机制
		
		2. volatile 内存语义:直接在主存中读写,而不是在自己的工作内存中读写。
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值