个人可以备案网站的内容,装修3d效果图怎么制作,网站用户黏度,网站建设报价单-中英文版并发和并行
并发
在同一时刻#xff0c;有多个指令在单个CPU上交替执行
并行
在同一时刻#xff0c;有多个指令在多个CPU上同时执行
多线程的实现方式
继承Thread类的方式 注意给线程设置名字#xff0c;启动线程等操作
实现Runable的方式
自己创建一个类然后去实现…
并发和并行
并发
在同一时刻有多个指令在单个CPU上交替执行
并行
在同一时刻有多个指令在多个CPU上同时执行
多线程的实现方式
继承Thread类的方式 注意给线程设置名字启动线程等操作
实现Runable的方式
自己创建一个类然后去实现Runable接口重写run方法
为什么会有这个方式
因为Java只支持单继承如果已经继承一个类了那么就不能继承第二个类所以有局限性。 创建一个Thread对象的时候传入创建的的重写类start()开启线程
问题
在使用自己实现的Runable接口的类的时候不能直接使用Thread类中的方法可以通过Thread.currentThread()获得当前执行run()函数的线程。
利用Callable接口和Future接口方式
为什么要实现Callable接口因为之前使用的多线程的函数中并没有返回值。 1、定义的类实现Callable接口并重写call()方法Callable中的泛型为返回值的类型 2、创建Future类它是一个抽象类所以应该创建它的子类FutureTask类来管理结果创建的时候传入实现Callable接口的对象。 3、创建Thread类的时候传入FutureTask的对象 4、执行Thread类中的start()方法 4、最后通过FutureTask对象获得结果
多线程中常用的成员方法 线程优先级
对于抢占式的线程具有优先级。Java中优先级为1-10创建一个线程默认为5 优先级越高在CPU上执行的概率越高。
守护线程
当其他非守护线程执行完毕之后守护线程会陆续结束 换个说法就是正常线程执行完毕了守护线程就没有存在的必要了
定义一个非守护线程 定义一个守护线程 创建对象并设置守护线程 结果非守护线程结束之后守护线程也结束了并不是马上存在一定的延迟
为什么会有守护线程
当把聊天窗关闭之后传输文件的线程就没有存在的必要了。
礼让线程 Thread.yield()为线程抢到CPU执行权之后让出使用权。重新抢线程。 仅仅会使两个线程执行的更加均匀并不是绝对均匀因为还要抢。
插入线程了解
有两个线程A和BB的线程中获得A线程的对象并且A线程的对象调用join()函数代表将A线程插入到当前B线程之前所以A执行完毕之后B才执行。
线程的生命周期 线程的安全问题
就是3个线程卖票然后出现卖重复和多余的票的问题。没啥好解释的。
同步代码块
为了保证操作的唯一性解决上面线程的安全问题所提出来的
synchronized(锁对象){}
这里锁对象可以理解为之前的flag标记只不过注意是唯一的就行改进
字节码对象可以使用当前类的字节码文件对象
同步方法
如果是想锁住 一整个方法那么使用同步方法也就是将synchronized加到方法上 1、同步方法是锁住方法里面所有的代码 2、锁住的对象不能像上面同步代码块那样能够自己指定对于非静态的方法中锁住的对象为this对于静态的方法为当前类的字节码文件对象 3、技巧对于那些不知道什么东西应该放到同步方法中的问题可以先写同步代码块然后将同步代码块放到同步方法中。
使用实现Runable的接口的方式进行展示
注意的点
这里面有一个要注意的地方就是之前使用类去继承Thread类的时候里面的ticket是static的 但是如果是实现Runable接口那么ticket就不用定义为static 因为如果继承Thread的话我们创建几个线程就创建几个Thread所以里面的ticket为static 我们如果实现Runable的话我们是创建几个Thread的时候输入实现Runable的对象所以不用为static 把他改成同步方法的形式
lock锁 之前的就是很省事这个lock就是很繁琐像是原本OS中精细化上锁解锁。还要考虑其他进程等待其他进程解锁的逻辑 下面这个函数会发生即使票卖出100个但是程序还是不会停止因为在100处直接break了没有进行解锁的操作导致其他线程一直等待锁 因此改成try catch finally的形式在finally中执行释放锁的操作
死锁
死锁是指两个或两个以上的进程在执行过程中由于竞争资源或者由于彼此通信而造成的一种阻塞的现象若无外力作用它们都将无法推进下去。
生产者消费者等待唤醒机制
就是那个一个桌子一个生产者一个消费者的情形。
生产者
package com.waitandnotify;public class Cook extends Thread{Overridepublic void run() {synchronized (Desk.lock){while (true){if(Desk.count 10){break;}if(Desk.flag 0){Desk.flag 1;Desk.lock.notifyAll();System.out.println(做了第Desk.count份);}else {try {Desk.lock.wait();} catch (InterruptedException e) {throw new RuntimeException(e);}}}}}
}消费者
package com.waitandnotify;public class Foodie extends Thread{Overridepublic void run() {synchronized (Desk.lock){while(true){if(Desk.flag 1){System.out.println(正在吃Desk.count);Desk.count;Desk.flag 0;//唤醒进程Desk.lock.notifyAll();}else {try {Desk.lock.wait();} catch (InterruptedException e) {throw new RuntimeException(e);}}if(Desk.count 10){break;}}}}
}测试类
package com.waitandnotify;public class Demo {public static void main(String[] args) {Cook cook new Cook();Foodie foodie new Foodie();cook.start();foodie.start();}
}等待唤醒机制阻塞队列实现 阻塞队列的继承结构
放的进程没有空间的时候会阻塞取的进程没有空间的时候会阻塞这就是通道啊。 ArrayBlockingQueue底层是数组所以在创建的时候要指定大小。
创建阻塞队列 实现生产者
注意阻塞队列都是一个所以定义一个成员变量 注意queue.put()个queue.take()中才是线程同步的代码run函数中其他部分不是同步的代码 所以输出的地方会出现重复的东西。
消费者 线程的状态 线程池
为什么会有线程池 例子吃饭A吃饭要买碗吃完就把碗摔了线程创建和消除也是这样很费资源。 自定义线程池 核心线程一直存在临时线程为当等待的任务占满了队伍并且有新的任务的时候创建临时进程其中定义了临时的时间如果超过定义的临时时间没有使用临时进程那么临时进程就销毁。如果提交的任务数量超过核心线程数量临时线程队伍长度触发任务拒绝策略。
任务拒绝策略 多线程额外扩展
看阿伟的文件不过找不到直接看八股文吧。