java中阶之线程

在这里插入图片描述

二十五.线程

1.作用:

​ 使代码可以同时执行多个事物

2.名词

进程:一个正在执行的程序
进程是程序的一次执行过程,或是正在运行的一个程序.是动态过程:有他自身的产生,存在,消亡
线程: 一个执行路径
线程是由进程创建的,是进程的一个实体,一个进程可以有多个线程
单线程:同一时刻,只允许执行一个线程
多线程:同一时刻,可以执行多个线程
主线程:一个线程创建时自带的一条线程,称为主线程
子线程:除主线程外都是子线程
守护线程(后台线程):
	特点:如果一个进程的前台线程全部被销毁,此时不管是否有守护线程正在执行,此时进程都将被回收
前台线程:
	特点:如果一个进程中有前台线程存活,此时系统将不会回收进程

3.组成:

CPU时间片

线程抢夺CPU执行权后可执行的时间

内存

一个线程一个栈内存,多个线程共享一个堆内存

4.线程的创建

继承Thread

方式一:
	创建Thread的子类对象
	步骤:
		1.创建一个类
		2.使其继承Thread
		3.重写run方法
	注意:当前线程启动后,将执行如方法中的代码
    	4.创建该类对象
    优点:可以创建无数个该类对象
    
  方式二:
  	使用匿名内部类的形式创建Thread的子类对象
  		步骤:
  			Thread 对象名 = new Thread(){
  				重写run方法
  			}
  		优点:便于书写
        缺点:只能创建一个该线程对象

实现Runnable接口

方式一:普通方式创建Runnable的子类对象
	步骤:
		1.创建一个类
		2.使其实现Runnable接口
		3.重写run方法
		4.创建该类对象
		5.在创建线程对象时传入该类对象(线程任务对象)

方式二:
	使用匿名内部类创建Runnable的子类对象
		步骤:
		1.Runnable 对象名 = new Runnable(){
			重写run方法
		};
		2.创建线程对象时传入该类对象(线程任务对象)

5.线程使用

5.线程的启动
线程对象.start();
注意:
	1.当线程启动后会开启新的执行路径,执行run方法中的代码
	2.如果直接使用线程对象调用run方法,不会开启新的执行路径
6.线程的销毁
线程已经启动,无法控制,需要等待执行完run方法中的代码
7.获取当前线程对象
+Thread.currentThread();
8.线程名城
获取线程名称:
	线程对象.getName();
修改线程名称
	线程对象.setName(name);
注意:在启动前修改	
9.线程优先级
作用:提高线程抢夺到CPU执行权的概率

语法:
	线程对象.setPriority(int);
注意:
	1.取值范围1-10;
	2.必须在线程启动前
10.线程休眠
作用:让线程暂时停止运行
方法:
	static void sleep(休眠时间);
注意:
	1.单位毫秒
	2.使用类调用,使当前线程休眠
	3.线程休眠期间不会抢夺CPU执行权
11.线程礼让
作用:将获取道德cpu执行权让出,重新参与抢夺
方法:
	static native void yield();
12.线程合并
作用:合并线程
方法:
	public final void join();
13.守护线程
有名:后台线程
特点:当一个进程中有前台线程存活,此时该进程就不会被系统回收
如果一个进程中只剩余后台线程,此时不管后台线程中的代码是否运行完毕,系统都将回收该进程
方法:
	public final void setDaemon(boolean on);
	true:表示守护线程,默认为false,表示前台线程
	注意:
		1.创建线程对象与主线程默认为前台线程
		2.必须在线程启动前

6.线程的生命周期

线程可以处于以下状态之一

1. NEW: 尚未启动的线程处于此状态
2. RUNNABLE:在java虚拟机中执行的线程处于此状态;内部会分为ready和running两部分,执行哪一个由调度器决定
3. BLOCKED: 被阻塞等待监视器锁定的线程处于此状态
4. WAITING :正在等待另一个线程执行特定动作的线程处于此状态
5. TIMED_WAITING :正在等待另一个线程执行动作达到指定等待时间的线程处于此状态(超时等待)
6. TERMINATED:一退出的线程出于此状态

在这里插入图片描述

7.Thread和Runnable的区别

1. 从java设计来看,通过继承Thread或者实现Runnable接口来创建线程本质上没有区别,从jdk帮助文档我们可以见到Tread类本身就实现了Runnable接口
2. 实现Runnable接口方式更加适合多个线程共享一个资源的情况,并且避免了单继承的限制

8.线程安全问题

原因:

多个线程操作同一数据,会导致线程安全问题

解决思路

保证同时只能有一个线程操作该数据

方案
方案一:同步代码块
	语法:
		synchronized(锁对象){
			要同步的代码
		}
	注意:
	1.所有对象都可以作为锁对象
    2.多个线程的锁对象要是同一个对象
方案二:同步方法
	语法:
		访问权限修饰符 synchronized 返回值类型 方法名(形参列表){
		}
	注意:
    	1.同步方法法人锁对象是this
    	2.多个线程的锁对象要是同一个对象
方案三:同步静态方法
	语法:
		访问权限修饰符 synchronized static 返回值类型 方法名(形参列表){
		
		}
	注意:
    	1.同步静态方法的锁对象是该类的对象
    		类对象:当JVM加载类时.会产生一个对象,该对象就是该类的类对象,一个类只有一个类对象
    	2.多个线程的锁对象要是同一个对象	

9.死锁

原因:

多个线程互相持有对方所需的锁资源

举例
Object A = new Object();
Object B = new Object();
线程1:
	xxx
	synchronized (A){
		xxx
		synchronized (B){
			xxx
		}
	}
线程2:
	xxx
	synchronized (B){
		xxx
		synchronized (A){
			xxx
		}
	}

避免思路

不要在同步中使用

10.线程间通讯

注意
1.线程间通讯的方法是由Object提供的
2.只能在同步中使用
3.只能使用所在的同步的锁对象调用
方法
唤醒线程
	notify():随机唤醒一个
	notifyAll():唤醒所有
	注意:只能唤醒以同一个对象调用wait方法的线程

线程休眠:
	wait() 无限休眠
	wait(int ms) 有限期休眠(休眠ms毫秒)
	wait(int ms,int ns)有限期休眠
	注意:
		ms为毫秒,ns为纳秒	
	

11.wait和sleep的区别

1.wait在休眠期会释放所持有的锁资源,sleep不会
2.wait必须在同步使用,sleep没有限制
3.wait必须使用所在的同步锁对象调用,sleep使用Thread类或者Thread类的对象调用
4.wait由Object提供,sleep由Thread类提供

13.线程池

作用:

​ 优化线程

原因:
一个线程大约占1MB的运行内存
大量创建线程时可能会导致内存溢出
大量的创建线程也导致需要对象线程频繁的创建与回收
思路
1.使用空闲的线程执行新的任务(线程复用)
2.使用一个容器来管理线程的创建,回收,复用等
注意:java中提出线程池来完成以上操作
线程池的体系结构
Executor(接口)
	提供的方法:
		void execute(Runnable command);
		作用:执行线程任务,子接口提供了submit优于该方法
	子类或子接口
    	ExecutorService(接口)
    		提供的方法:
    			void shutdown();
    			作用:关闭线程池
    			boolean isShutdown();
    			作用:判断线程池是否关闭
    			Future<T> submit(线程任务)
    			作用:提交线程任务
    		子类或子接口:
            	ScheduledExecutorService(接口)
            	ThreadPoolExecutor(类)
            		构造函数:
            			public ThreadPoolExecutor(int corePoolSize,
            						int maxmumPoolSize,
            						long keepAliveTime,
            						TimeUnit unit,
            						BlockingQueue<Runnable> workQueue,
            						ThreadFactory threadFactory,
            						RejectedExecutionHandler handler)
            						
            		corePoolSize:h核心线程数,线程池中最少有几个线程
                    maximumPoolSize:最大线程数,线程中最多可以容纳的线程数
                    keepAliveTime:销毁时间,当线程执行完任务后,多久销毁
                    until:时间单位
                    workQueue:存储执行的线程任务的集合(队列形式)
                    threadFactory:创建线程
                    handler:优化线程,使其线程复用的算法
Executors
作用:创建线程池
原因:应为ThreadPoolExecutor过于麻烦,所以JDK提供该类帮助我们创建线程池提供的方法

	1.固定线程池
	特点:线程池中的线程数量恒定,当线程任务小于线程数量时,随机在线程池中挑选线程执行任务,当线程任务大于线程数量,会先执行前面的任务,后等前面任务执行完毕后,使用执行完毕的线程,执行剩余任务.
    static ExecutorService newFixedThreadPool(int nThreads)
    	nThreads:线程池中线程的数量
    	
    2.可变线程池
    特点:线程池中的线程数量可变
    static ExecutorService newCachedThreadPool()
    
    3.单例线程池
    特点:一个线程池只有一个线程
    static ExecutorService newSingleThreadExecutor()
    
    4.抢占线程池
    static ExecutorService newWorkStealingPool()
    
    5.调度线程池
    特点:该线程池执行任务可以延迟,也可以延迟重复执行
    static ScheduledExecutorService newScheduledThreadPool(int corePoolSize)
    corePoolSize:线程池中线程的数量
    
    6.单例调度线程池
    特点:调度线程池中只有一个线程
    static ScheduledExecutorService newSingleThreadScheduledExecutor();
线程池的使用
步骤:
1.创建线程池
2.提交任务
3.关闭线程池
调度线程池:ScheduledExecutorService
提供的方法:
	public ScheduledFuture<?> schedule(线程任务,long delay,TimeUnit unit)
	作用:延迟执行   
public ScheduledFuture<?> scheduleAtFixedRate(Runnable command
											long initialDelay
											long period
											TimeUnit unit);
	作用:延迟重复执行
    1参,执行的任务
    2参,延迟时间
    3参,间隔时间 = 本次任务开始时间 - 上次任务开始时间
    注意:如果上次任务执行时间>间隔时间,那么当上次任务执行完毕后,本次任务直接开始
   4参,时间单位
public ScheduledFuture<?> scheduleWithFixedDaley(Runnable command,
											long initialDelay
											long delay
											TimeUnit unit);
	作用:延迟重复执行
    1参,执行任务
    2参,延迟时间
    3参,间隔时间= 本次任务开始时间-上次任务结束时间
    4时间单位

14.Callable

作用:有返回值的线程任务对象

注意:无法在创建Thread对象时传入,必须配合线程池使用

15.Lock

作用:简化同步

同步:
同步代码块
	synchronize(锁对象){
		//关锁
		代码
		//开锁
	}
同步方法
	访问权限修饰符 synchronize 返回值类型 方法名(形参列表){
		//关锁
		方法
		//开锁
	}
同步静态方法
	访问权限修饰符 synchronize static 返回值类型 方法名(形参列表){
		//关锁
		方法
		//开锁
	}
lock体系
Lock
	提供的方法:
		void lock():关锁
		void unLock():开锁
		
	Condition newCondition():获取锁对象
			void await():无限期休眠
			void signal():随机唤醒一个
			void signalAll():唤醒所有
	子类:
		ReentrantLock
		
ReadWriteLock
	提供的方法:
		Lock readLock():获取读锁
		Lock writeLock():获取写锁
		注意:
			读-写	互斥
			读-读 不互斥
			写-写	互斥
	子类
		ReentrantReadWriteLock
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

半糖不加奶

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

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

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

打赏作者

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

抵扣说明:

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

余额充值