多线程
-
创建线程方式1:继承Thread类,重写run()方法,调用start开启线程
-
创建线程方式2:实现runnable接口,重写run方法,执行线程需要丢入runnable接口实现类,调用start方法
-
注意:线程开启不一定立即执行,由CPU调度执行
Thread.start()线程开启
Thread.sleep(100) 模拟延时
Thread.currentThread().getName() 当前线程
静态代理
真实对象和代理对象都要实现同一个接口
代理对象要代理真实角色
好处
代理对象可以做很多真实对象做不了得事情
真实对象专注做自己得事情
lambda表达式
- 理解Functional interface(函数式接口) 是学习java8 lambda表达式的关键所在。
- 为什么要使用lmabda表达式
- 避免匿名内部类定义过多
- 可以让你的代码看起来很简洁
- 函数式接口的定义
- 任何接口,如果只包含唯一一个抽象方法,那么它就是一个函数式接口
- 对于函数式接口,我们可以通过lambda表达式来创建该接口的对象
- labda表达式总结:
- lambda表达式只能有一行代码的情况下才能简化成为一行,如果有多行,那么就用代码快包裹
- 前提是接口为函数式接口
- 多个参数化也可以去掉参数类型,要去掉就都去掉,必须加上括号
线程休眠
- sleep(时间)指定当前线程阻塞的毫秒数;
- sleep存在异常InterruptedException;
- sleep时间达到后线程进入就绪状态;
- sleep可以模拟网络延时,倒计时等
- 每一个对象都有一把锁,sleep不会释放锁
线程礼让
Thread.yield();
当线程执行的时候碰到Thread.yield();就会先退出来进入就绪状态,让另一个线程先跑。
注意:礼让有时候不一定能成功,看CPU心情
Join
- join合并线程,待此线程执行完成后,在执行其他线程,其他线程阻塞
线程的状态
new - 就绪状态 - 阻塞状态 或者 运行状态 - dead 有五个状态
线程中断或者结束,一旦进入死亡状态,就不能再次启动
线程优先级
-
现成的优先级用数字表示,范围从1-10,默认是5
-
//放置优先权 .setPriority(3) // 表示最大的 10 .setPriority(Thread.MAX_PRIORITY); //表示最小的1 setPriority(Thread.MIN_PRIORITY);
-
//得到优先权,可以显示出几级 Thread.currentThread().getPriority()
-
-
注意
- 优先级低只是意味着获得调度的概率低,并不是优先级低就不会被调用了,这都是看CPU的调度
守护线程
-
线程分为用户线程和守护线程
-
虚拟机必须确保用户线程执行完毕
-
虚拟机不用等待守护线程执行完毕
//守护线程 .setDaemon(true);
线程同步
- 由于同一进程的多个线程共享同一块存储空间,在带来方便的同时,也带来了访问冲突问题,为了保证数据在方法中被访问时的正确性,在访问时加入锁机制 synchronized,当一个线程获得对象的排他锁,独占资源,其他线程必须等待,使用后释放锁即可,存在以下问题:
- 一个线程持有锁会导致其他所有需要此锁的线程挂起;
- 在多线程竞争下,加锁,释放锁会导致比较多的上下文切换和调度延时,引起性能问题;
- 如果一个优先级高的线程等待一个优先级低的线程释放锁 会导致优先级倒置,引起性能问题。
- synchronized 同步方法 锁的对象就是变化的量,需要增删改的对象
同步块
死锁
- 多个线程各自占有一些共享资源,并且互相等待其他线程占有的资源才能运行,而导致两个或则多个线程都在等待对方释放资源,都停止执行的情形。某一个同步块同时拥有“两个以上对象的锁”时,就不会发生“死锁”的问题
死锁避免方法
-
产生死锁的四个必要条件:
- 互斥条件:一个资源每次只能被一个进程使用。
- 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
- 不剥夺条件:进程以获得的资源,在未使用完之前,不能强行剥夺。
- 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。
上列出了死锁的4个必要条件,只要破其中一个或多个就可以避免死锁发生
线程通信
wait() :表示线程一直等待,直到其他线程通知,与sleep不同,会释放锁
notifyAll() :唤醒同一个对象上所有调用wait()方法的线程,优先级别高的线程优先调度
线程池
-
好处:
- 提高响应速度(减少了创建新线程的时间)
- 降低资源消耗(重复利用线程池中线程,不需要每次都创建)
- 便于县线程管理
使用线程池
- ExecutorService:真正的线程池接口。常见子类ThreadPoolExecutor
- void execute(Runnable command):执行任务/命令,没有返回值,一般用来执行Runnable
- Futuresubmit(Callabletask):执行任务,有返回值,一般用来执行Callable
- void shutdown():关闭线程池
- Executors:工具类、线程池的工厂类,用于创建并返回不同类型的线程池
//线程池 public class Test13 { public static void main(String[] args) { //1.创建服务,创建线程池 //.newFixedThreadPool(10); 参数为线程池的大小 ExecutorService service = Executors.newFixedThreadPool(10); //线程池启动服务 service.execute(new MyThread()); service.execute(new MyThread()); //2.关闭链接 service.shutdown(); } } class MyThread implements Runnable{ @Override public void run() { System.out.println(Thread.currentThread().getName()); } }