多线程
一、创建方式:
1.继承Thread类(重点)
2.实现Runnable接口(重点)
3.实现Callable接口(了解)
二、.Lamda表达式
1.简洁代码
2.避免匿名内部类定义过多
3.关键:函数式接口:一个接口只包含一个抽象式方法
比如:public interface Runnable{
public abstract void run();
}
三、代理模式
1.Thread实现Runnable接口,Thread是Runnable的代理。因为Runnable只有一个run方法,需要借助Thread
帮助调用start方法去启动线程。
2.例如:结婚是一个事件,结婚的人和婚庆公司是两个实现,而婚庆公司可以帮助结婚的人实现一些他无法实现的方法。
婚庆公司就是这个人的代理
四、线程的几个功能
①线程停止:设置一个标识符Boolean flag=true; 再设只停止标识符,修改flag让线程自动停止。
②线程休眠:
Thread.sleep:每个对象都有一把锁,sleep不会释放锁
模拟网络时延:放大问题的发生性:抢票
模拟倒计时:延迟1秒
打印当前时间:延迟1秒
③线程礼让
调用yield方法,让主线程让位
④观测线程状态
* NEW
* 至今尚未启动的线程处于这种状态。
* RUNNABLE
* 正在 Java 虚拟机中执行的线程处于这种状态。
* BLOCKED
* 受阻塞并等待某个监视器锁的线程处于这种状态。
* WAITING
* 无限期地等待另一个线程来执行某一特定操作的线程处于这种状态。
* TIMED_WAITING
* 等待另一个线程来执行取决于指定等待时间的操作的线程处于这种状态。
* TERMINATED
* 已退出的线程处于这种状态。
⑤线程保护thread.setDaemon(true)
五、并发
前提:遇到多条线程共用一个对象例如抢票;利用并发来解决
形成并发条件:队列+锁
synchronized方法控制对对象的访问,每个对象对应一把锁,
每个synchronized方法都必须获得调用该方法的对象的锁才能执行,否则线程会阻塞
方法一旦执行,就独占锁,直到该方法返回才释放锁,后面被阻塞的线程才能获得锁,继续执行
缺点:如果将一个大的方法申明为synchronized将会影响效率
//生产者和消费者:生产者,消费者,产品,缓冲区 Producer, consumer, product, buffer
//管程法
//在选择创建线程的时候,我们就需要想清楚谁是线程,谁是主体,不是盲目随便创建,随便继承Thread
//在继承Thread的时候该类继承他的所以方法,可以直接去调用start方法
//在实现Runnable接口的时候,我们需要去寻找代理new Thread对象才能去调用start方法开启线程,
public class Demo17 {
public static void main(String[] args) {
Buffer buffer=new Buffer();
new Prodeucer(buffer).start();
new consumer(buffer).start();
}
}