当前位置: 首页 > wzjs >正文

网站建设403武汉外包seo公司

网站建设403,武汉外包seo公司,汽车可以做哪些广告视频网站,电商网站项目经验介绍ppt模板我对未来没有底气 我也不知道当下该如何做 那就活着,活着就能把日子过下去 ---------陳長生. 1.多线程案例 1.1.单例模式 单例模式是常见的设计模式之一 设计模式:一些编程大佬制定的一些通用代码,再特定的场景下能套用进去,即…

我对未来没有底气

我也不知道当下该如何做

那就活着,活着就能把日子过下去

                                                                                                                                    ---------陳長生.


1.多线程案例

1.1.单例模式

        单例模式是常见的设计模式之一

        设计模式:一些编程大佬制定的一些通用代码,再特定的场景下能套用进去,即使是小白也能使用。

        单例模式能保证类在程序中只有一个实例,不会创建多个实例。

        单例模式中常用的便是”饿汉模式“和”懒汉模式“。

1.1.1饿汉模式

//饿汉模式
class Singleton{//创建类时就创建实例private static Singleton instance =new Singleton();//提供方法获取实例public static Singleton getInstance(){return instance;}//构造方法私有化,防止外部创建实例private Singleton(){}
}

饿汉模式在创建实例时就创建实例化对象。   

1.1.2懒汉模式

//懒汉模式
class Singletonlan{//创建实例赋值为空private static Singletonlan instance =null;//静态的锁对象,保证原子性//volatile关键字:保证可见性,禁止指令重排序//防止指令重排序:在创建实例时,可能会发生指令重排序,导致其他线程获取到未初始化的实例private static volatile Object lock=new Object();//构造方法私有化,防止外部创建实例public static Singletonlan getInstance(){//先判断是否为空,为空则创建if(instance==null){//保证原子性synchronized(lock){//再次判断是否为空,为空则创建if(instance==null){instance =new Singletonlan();}}}//返回实例return  instance;}
}

懒汉模式则是在需要的时候才实例化对象

懒汉模式逐步解析:
synchronized:

        因为线程运行是随机性的,所以我们要加上synchronized保证线程的原子性。

双重if:

        内部if语句:但instance为空时则为其实例化,反之直接返回,这个好理解。

        外部if语句:我们只需要在第一次没有实例化赋值的时候获取锁就好了,因为单例模式只需要只需要一个实例。假设我们去掉外部的if语句,那是不是每次不管他有没有创建实例都得进行获取锁和解锁操作,这就大大降低了时间效率,这时候我们就需要在外部加个if语句判断它是否为空。

指令重排序:

        指令重排序是编译器提供的优化功能,能够调整一些指令的运行顺序

         我们在创建实例时,在编译器背后会有三条指令:1.为对象申请空间,2.初始化对象,3.将内存地址保存在引用变量中。

        那我们设想一下,本来1,2,3的执行顺序被指令重排序后,线程先执行了1,3这两条指令后,线程2一下执行了三条指令,这时候的线程2拿到的是线程1没有初始化的变量,那么运行出来的结果我们是不可想象的。        

1.2.阻塞队列

1.2.1.阻塞队列是什么

  • 阻塞队列是一种特殊的队列,遵循着“先进先出”原则
  • 阻塞队列是一种线性安全的数据结构
  • 当队列为空的时候,继续出队列会堵塞,直到有其他线程往队列中插入元素
  • 当队列为满的时候,继续入队列会堵塞,直到有其他线程往队列中取出元素
  • 是一种典型的“生产者和消费者模型”

1.2.2.生产者消费者模型

        生产者消费者模型就是通过一个容器,存储生产者生产的东西,然后消费者在从其中取出

阻塞队列相当于一个缓存区,平衡了生产者和消费者之间的平横关系

        例如:双十一淘宝做活动的时候,有大量的人进入淘宝进行购物操作,如果是生产者和消费者直接沟通,那么如此庞大的任务量就会造成系统崩溃

        这种情况就像我们抢选修课的时候,一大批人进入选课系统进行选课操作,就会导致很多人加载不进选课系统,这种就是生产者和消费者直接沟通

        

        但是淘宝在生产者和消费者之间构建了阻塞队列,所以在双十一这种活动的时候并不会出现我们选课系统的这种情况。

阻塞队列也能使生产者和消费者之间“解耦”:

        例如:在工厂中的某一条流水线作业上,长生员工(生产者)负责组装工作,陈依(消费者)负责产品的贴码和扫码录入操作

        高耦合:陈依等待着长生将产品组装完再进行贴码和扫码,如果长生装的慢的话,陈依就得等长生;如果装的快的话,陈依跟不上长生的速度,长生就得等陈依,这就称为高耦合,大大降低了时间效率。

        低耦合:假设在长生和陈依之间放个框子,长生将做好的产品放入框子中,陈依则直接从框子中取得产品直接进行贴码和扫码操作,这样长生装的快的话就不用一件一件的给陈依了,这就称为低耦合,提高了时间效率。

1.2.3.标准库中的阻塞队列

JAVA的标准库中自带了阻塞队列BlockingQueue,我们需要的时候直接使用就好了

  • BlockingQueue是接口,真正实现的是LinkedBlockingQueue
  • 该类的 put() 和 take() 方法提供了阻塞功能 
  • 虽然也有其他的方法,但是他们不提供阻塞功能
生产者消费者模型创建:
package Thread;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
public class text1 {public static void main(String[] args) {//生产者模型//实例化阻塞队列BlockingQueue<Integer> blockingQueue=new LinkedBlockingQueue<>();//生产线程Thread t1=new Thread(()->{//生产数据int count=0;//一直执行任务while(true){   try{//将数据放入阻塞队列blockingQueue.put(count);System.out.println("生产数据"+count);//持续生产数据count++;//线程休眠(0.5秒执行一次任务)Thread.sleep(500);}catch(InterruptedException e){e.printStackTrace();}}});//消费者模型Thread t2=new Thread(()->{while(true){try{//从阻塞队列中取出数据int n=blockingQueue.take();System.out.println("消费数据"+n);}catch(InterruptedException e){e.printStackTrace();}}});t1.start();t2.start();}
}

1.2.4.阻塞队列的实现

  • 通过“循环队列”来实现
  • put();插入元素时,如果队列满了就堵塞,反之就加入数据
  • take():取出元素时,如果队列为空就堵塞,反之就取出数据
package Thread;public class text2 {//模拟实现阻塞队列private int[] array=new int[1000];//定义头和尾private int head=0;private int tail=0;//定义队列长度private int size=0;//定义锁private volatile Object lock=new Object();//模拟实现构造put()方法public void put(int val) throws InterruptedException{//保证原子性synchronized(lock){//如果队列满了,就堵塞while(size==array.length){lock.wait();}//如果队列没满,就放入数据array[tail]=val;//更新tailtail++;//如果tail到达数组末尾,就从头开始if(tail==array.length){tail=0;}//更新队列长度size++;//唤醒等待线程lock.notify();}}//模拟实现take()方法public int take() throws InterruptedException {//保证原子性synchronized(lock){//如果队列为空,就堵塞while(size==0){lock.wait();}//如果队列不为空,就定义一个返回值取出队列int ret=array[head];//更新headhead++;//如果head到达数组末尾,就从头开始if(head==array.length){head=0;}//更新队列长度size--;//唤醒等待线程lock.notify();//返回值return ret;}}public static void main(String[] args) {//生产者模型//实例化阻塞队列text2 blockingQueue=new text2();//生产线程Thread t1=new Thread(()->{//生产数据int count=0;//一直执行任务while(true){   try{//将数据放入阻塞队列blockingQueue.put(count);System.out.println("生产数据"+count);//持续生产数据count++;//线程休眠(0.5秒执行一次任务)Thread.sleep(500);}catch(InterruptedException e){e.printStackTrace();}}});//消费者模型Thread t2=new Thread(()->{while(true){try{//从阻塞队列中取出数据int n=blockingQueue.take();System.out.println("消费数据"+n);}catch(InterruptedException e){e.printStackTrace();}}});t1.start();t2.start();}
}

1.3.线程池

1.3.1.线程池是什么

概念:
  • 线程池就是几个线程的集合
  • 一个线程池中分为核心线程和临时线程
  • 核心线程:相当于公司的正式员工
  • 核心线程:相当于公司的实习生,在需要的时候用,不需要的时候直接抄鱿鱼~
为什么使用线程池:

        假设长生要去出差,那么出去的花销公司要报销

        情况一(不使用线程池):做一件事报销一次,住宿提交一次财务申请,吃饭提交一次财务申请,材料提交一次财务申请·····

        情况二(使用线程池):事先获得一笔经费,当需要的时候直接使用这笔钱,最后回到公司报告时多退少补。

        所以使用线程池之后就能提高效率,大大节省时间的开销。

1.3.2.标准库中的线程池

    JAVA提供了ExecutorService管理多线程的接口

newFixedThreadPool()创建固定线程池
newCachedThreadPool()创建缓存线程池,长度为“int的最大值”
newSingleThreadPool()创建单个线程池,长度为1
newScheduledThreadPool()       创建定时线程池,长度为动态增长
package Thread;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class Demo3 {public static void main(String[] args) {//创建固定值为10的线程池ExecutorService pool1=Executors.newFixedThreadPool(10);//创建缓存线程池,长度为“int的最大值”ExecutorService pool2=Executors.newCachedThreadPool();//创建单个线程池,只有一个线程ExecutorService pool3=Executors.newSingleThreadExecutor();//创建一个定时任务线程池,长度为动态增长ExecutorService pool4=Executors.newScheduledThreadPool(10);}
}

1.3.3.实现线程池

  • 使用BlickingQueue阻塞队列存储任务
  • 定义submit()方法读取任务放入阻塞队列中
  • 在MyFixThreadPool类中创建线程并读取队列中的任务执行
package Thread;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;class MyFixThreadPool{ //定义一个阻塞队列private BlockingQueue<Runnable> queue =new LinkedBlockingQueue<>();//定义构造方法,创建线程池,n为线程池的长度public MyFixThreadPool(int n){//创建n个线程,执行任务for(int i=0;i<n;i++){ //创建线程Thread t=new Thread(()->{try{//重阻塞队列取出任务执行while(true){Runnable task=queue.take();task.run();}}catch(InterruptedException e){e.printStackTrace();}});//启动线程t.start();}}//定义submit()方法,提交任务public void submit(Runnable task) throws InterruptedException {//往阻塞队列中放入任务queue.put(task);}
}public class Demo4 {public static void main(String[] args) throws InterruptedException {MyFixThreadPool pool=new MyFixThreadPool(10);pool.submit(new Runnable() {@Overridepublic void run() {System.out.println("hello world");}});}
}   

1.4.定时器

1.4.1.定时器是什么

  • 定时器相当于现实中的闹钟,到达某个指定的时间时,就执行任务。
  • 定时器是开发中非常常用的组件,例如对方在500ms内没有回复,就断开连接

1.4.2.标准库中的定时器

  • 标准库中提供了一个Timer类,并提供了schedule()方法
  • schedule()方法包含两个参数,一个参数为要执行的任务,一个为指定的时间(毫秒为单位)
import java.util.Timer;
import java.util.TimerTask;public class Demo5 {public static void main(String[] args) {//创建定时器Timer timer=new Timer();//创建定时任务,调用schedule方法timer.schedule(new TimerTask() {//执行任务@Overridepublic void run() {System.out.println("定时任务执行了");}//指定时间执行}, 1000 );}
}

http://www.dtcms.com/wzjs/111032.html

相关文章:

  • 网站建设公司资讯培训网站搭建
  • wordpress做社交网站江苏网站建设推广
  • 重庆网站制作一般多少钱小红书推广价目表
  • 佛山做网站的哪个好bing搜索引擎国际版
  • 可以做渗透的网站百度网址大全下载
  • 茶叶网站建设太原做网站哪家好
  • 郴州文明网网站市场营销师报名官网
  • 个人如何做问答类网站网络营销服务外包
  • 网站建设托管定制微信小程序怎么制作自己的程序
  • asp网站 证书实训百度搜索引擎的总结
  • 征婚网站上拉业务做恒指期货武汉网站seo服务
  • php网站开发技术文档南京seo公司教程
  • 企业管理平台系统网站网络营销app有哪些
  • 中国建设银行网站-诚聘英才海南百度推广电话
  • wordpress 迅雷seo和sem的关系
  • 哪个网站可以做司考题站长工具站长
  • 建筑网站知名度seo在线培训课程
  • 网站建设服务费属于什么费用sem什么意思
  • 服装代销的网站源码下载百度推广app
  • 闸北专业做网站sem竞价推广代运营收费
  • 制作网站的方法打开官方网站
  • 广州公司网站开发seo平台
  • 建湖做网站哪家最好百度明星人气榜排名
  • 苏州工业园区规划建设局网站广告联盟点击赚钱平台
  • 动态网站建设名词解释武汉seo软件
  • 广州做网站系统全球疫情最新消息
  • b2c网站建设平台站长工具seo排名
  • 衡水专业网站建设公司网站注册域名
  • 医院网站设计怎么做百度入口
  • 怎么在百度上做网站推广网站流量查询站长之家