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

做网站一年网站页面优化内容包括哪些

做网站一年,网站页面优化内容包括哪些,wordpress+头像加速,黑河做网站哪家好文章目录 一、线程间的通信(1)为什么要处理线程间的通信(2)等待唤醒机制 二、案例(1)案例1、创建线程2、解决线程安全问题3、等待4、唤醒5、同步监视器 (2)调用wait和notify需注意的…

文章目录

  • 一、线程间的通信
    • (1)为什么要处理线程间的通信
    • (2)等待唤醒机制
  • 二、案例
    • (1)案例
      • 1、创建线程
      • 2、解决线程安全问题
      • 3、等待
      • 4、唤醒
      • 5、同步监视器
    • (2)调用wait和notify需注意的细节
  • 三、wait与sleep的区别

一、线程间的通信

(1)为什么要处理线程间的通信

当我们需要多个线程共同完成一件任务,并且我们希望他们有规律的执行,那么多线程之间需要一些通信机制,可以协调它们的工作,以此实现多线程共同操作一份数据。(在同步的基础之上解决通信的问题)

比如:线程A用来生产包子的,线程B用来吃包子的,包子可以理解为同一资源,线程A与线程B处理的动作,一个是生产,一个是消费,此时B线程必须等到A线程完成后才能执行,那么线程A与线程B之间就需要线程通信,即—— 等待唤醒机制。

(2)等待唤醒机制

这是多个线程间的一种协作机制

谈到线程我们经常想到的是线程间的竞争(race),比如去争夺锁,但这并不是故事的全部,线程间也会有协作机制

在一个线程满足某个条件时,就进入等待状态(wait() / wait(time)), 等待其他线程执行完他们的指定代码过后再将其唤醒(notify());

或可以指定wait的时间,等时间到了自动唤醒;

在有多个线程进行等待时,如果需要,可以使用 notifyAll()来唤醒所有的等待线程。wait/notify 就是线程间的一种协作机制。

  1. wait:线程不再活动,不再参与调度,进入 wait set 中,因此不会浪费 CPU 资源,也不会去竞争锁了,这时的线程状态是 WAITING 或 TIMED_WAITING。它还要等着别的线程执行一个特别的动作,也即“通知(notify)”或者等待时间到,在这个对象上等待的线程从wait set 中释放出来,重新进入到调度队列(ready queue)中。
  2. notify:则选取所通知对象的 wait set 中的一个线程释放。
  3. notifyAll:则释放所通知对象的 wait set 上的全部线程。

🗳️注意:

被通知的线程被唤醒后也不一定能立即恢复执行,因为它当初中断的地方是在同步块内,而此刻它已经不持有锁,所以它需要再次尝试去获取锁(很可能面临其它线程的竞争),成功后才能在当初调用 wait 方法之后的地方恢复执行。

总结如下:

  • 如果能获取锁,线程就从 WAITING 状态变成 RUNNABLE(可运行) 状态;
  • 否则,线程就从 WAITING 状态又变成 BLOCKED(等待锁) 状态

二、案例

(1)案例

🌋案例描述:

使用两个线程打印 1-100。线程1, 线程2 交替打印。

🍰分析

1、创建线程

这里使用实现的方式创建线程。

class PrintNumber implements Runnable{//共享100private int number=1;@Overridepublic void run() {}
}

run方法里面写上逻辑代码:

class PrintNumber implements Runnable{//共享100private int number=1;@Overridepublic void run() {//打印数据while(true){if(number<=100){System.out.println(Thread.currentThread().getName()+":"+number);number++;}else{break;}}}
}

main方法中创建两个线程,如下:

public class PrintNumberTest {public static void main(String[] args) {//创建PrintNumber类的实例PrintNumber p=new PrintNumber();Thread t1=new Thread(p,"线程1");Thread t2=new Thread(p,"线程2");t1.start();t2.start();}
}

关于number的问题,需要考虑同步

if中加一个sleep,将问题放大。

目前的代码如下:

public class PrintNumberTest {public static void main(String[] args) {//创建PrintNumber类的实例PrintNumber p=new PrintNumber();Thread t1=new Thread(p,"线程1");Thread t2=new Thread(p,"线程2");t1.start();t2.start();}
}class PrintNumber implements Runnable{//共享100private int number=1;@Overridepublic void run() {//打印数据while(true){if(number<=100){try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName()+":"+number);number++;}else{break;}}}
}

输出:

image.png

可以看到打印出了错误信息。


2、解决线程安全问题

现在我们使用同步代码块来解决线程安全问题。

将操作number的代码用synchronized包裹起来,就是下面蓝色部分:

image.png

synchronized包裹的时候,不能包裹少了,那样会有安全问题。

若是包裹多了,串行的场景就会更多,导致效率变低。

所以,操作共享数据的代码,不能包裹多,也不能少。

🌱代码

package yuyi04.Communication;/*** ClassName: PrintNumberTest* Package: yuyi04.Communication* Description:*  使用两个线程打印 1-100。线程1, 线程2 交替打印。* @Author 雨翼轻尘* @Create 2024/2/2 0002 14:57*/
public class PrintNumberTest {public static void main(String[] args) {//创建PrintNumber类的实例PrintNumber p=new PrintNumber();Thread t1=new Thread(p,"线程1");Thread t2=new Thread(p,"线程2");t1.start();t2.start();}
}class PrintNumber implements Runnable{//共享100private int number=1;@Overridepublic void run() {//打印数据while(true){synchronized (this) {   //当前this表示PrintNumber的实例,即p,是唯一的if(number<=100){try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName()+":"+number);number++;}else{break;}}}}
}

🍺输出

image.png

可以看到现在的线程是安全的。


3、等待

紧接着需要考虑下一个问题,需要将两个线程交替打印

🎲如何实现交替?

比如线程1进入同步代码块,然后打印结束,出了同步代码块。

此时线程1需要进入阻塞状态,让线程2进入同步代码块输出执行,才能保证与线程1交替执行。

如何让线程1处于阻塞,这里需要使用一个方法wait(),让它处于等待状态。如下:

image.png

线程一旦执行wait()方法,就进入等待状态(阻塞),同时会释放对同步监视器的调用

wait()方法有一个异常需要处理一下:

image.png

注意,sleep()不会释放同步监视器,这一点需要注意。

有时候面试会问,wait()sleep()有什么区别?

这就是其中一个区别,sleep()不会释放对同步监视器的调用,而wait()会释放对同步监视器的调用。

🌱代码

public class PrintNumberTest {public static void main(String[] args) {//创建PrintNumber类的实例PrintNumber p=new PrintNumber();Thread t1=new Thread(p,"线程1");Thread t2=new Thread(p,"线程2");t1.start();t2.start();}
}class PrintNumber implements Runnable{//共享100private int number=1;@Overridepublic void run() {//打印数据while(true){synchronized (this) {   //当前this表示PrintNumber的实例,即p,是唯一的if(number<=100){try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName()+":"+number);number++;try {wait(); //线程一旦执行此方法,就进入等待状态(阻塞),同时会释放对同步监视器的调用} catch (InterruptedException e) {e.printStackTrace();}}else{break;}}}}
}

🍺输出

image.png

☕注意

一旦线程1进入同步代码块执行到wait(),就会释放对同步监视器的调用,然后开始等待操作。

线程2就可以拿着同步监视器进入同步代码块了,当线程2执行到wait(),它也开始等待。

所以两个线程都处于等待状态,只能输出两个数字,然后进入了阻塞状态


4、唤醒

🎲如何不一直等待下去呢?

Ctrl+P可以看到wait()方法还有带参的,可以设置等待时间,就是达到时间自动醒来。如下:

image.png

现在我们不使用这个了,因为想让它们交互输出,可以考虑唤醒线程。

线程1进入同步代码块执行到wait(),然后释放同步监视器,线程2进入同步代码块。

所以我们需要在线程2wait()之前把线程1唤醒

可以在这里写上notify(),如下:

image.png

🍰分析一下现在的情况:

线程1进入同步代码块,碰到了notify(),发现没有可以唤醒的线程,就继续往后执行。

然后线程1打印了“1”,接下来执行到wait(),开始等待,并且释放同步监视器。

线程2拿到锁,进入同步代码块,碰到了notify(),发现线程1在等待,就将线程1叫醒,虽然叫醒了,但是没有用,因为已经没有同步资源了。

线程2就拿着锁继续执行,即使sleep也不影响自动睡醒之后继续往后执行(sleep不会导致锁被释放),然后输出“2”。

线程2执行到wait(),就开始等待了,同时也释放同步监视器。

此时线程1是醒着的状态,从被wait()的地方继续往后执行,后边要是有代码的话还需要继续执行,然后拿着锁再次进入同步代码块,然后碰到notify(),将线程2叫醒。

🌱代码

package yuyi04.Communication;/*** ClassName: PrintNumberTest* Package: yuyi04.Communication* Description:*  使用两个线程打印 1-100。线程1, 线程2 交替打印。* @Author 雨翼轻尘* @Create 2024/2/2 0002 14:57*/
public class PrintNumberTest {public static void main(String[] args) {//创建PrintNumber类的实例PrintNumber p=new PrintNumber();Thread t1=new Thread(p,"线程1");Thread t2=new Thread(p,"线程2");t1.start();t2.start();}
}class PrintNumber implements Runnable{//共享100private int number=1;@Overridepublic void run() {//打印数据while(true){synchronized (this) {   //当前this表示PrintNumber的实例,即p,是唯一的notify();if(number<=100){try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName()+":"+number);number++;try {wait(); //线程一旦执行此方法,就进入等待状态(阻塞),同时会释放对同步监视器的调用} catch (InterruptedException e) {e.printStackTrace();}}else{break;}}}}
}

🍺输出(部分)

image.png

现在看到的就是交互的场景。


5、同步监视器

🗳️关于同步监视器

这里其实省略了this,如下:

image.png

wait同理:

notify();   //this.notify();
wait();		//this.wait();

凡是在方法当中,没有写是谁调用的,如果是非静态方法,那就少了this。

若是静态方法,那就是当前类。

这里的this必须是一样的吗?如下:

image.png

我们先来自己定义一个同步监视器,然后将obj放入:

image.png

🌱代码

public class PrintNumberTest {public static void main(String[] args) {//创建PrintNumber类的实例PrintNumber p=new PrintNumber();Thread t1=new Thread(p,"线程1");Thread t2=new Thread(p,"线程2");t1.start();t2.start();}
}class PrintNumber implements Runnable{//共享100private int number=1;Object obj=new Object();@Overridepublic void run() {//打印数据while(true){synchronized (obj) {   //obj是唯一的,线程安全this.notify();   //notify();if(number<=100){try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName()+":"+number);number++;try {wait(); //线程一旦执行此方法,就进入等待状态(阻塞),同时会释放对同步监视器的调用} catch (InterruptedException e) {e.printStackTrace();}}else{break;}}}}
}

🍺输出

image.png

会报一个异常IllegalMonitorStateException,这表示当前使用的同步监视器(即obj)和notify()wait()方法的调用者不一致。

所以,它们的调用者,必须是同步监视器。(这里也可以看出,notifywait方法必须要在同步代码块或同步方法中使用,只有这两个结构中才存在同步监视器,Lock里面没有同步监视器)


🚗处理

既然现在的同步监视器是obj,那么就用obj去调用notifywait方法即可。

如下:

image.png

🌱代码

package yuyi04.Communication;/*** ClassName: PrintNumberTest* Package: yuyi04.Communication* Description:*  使用两个线程打印 1-100。线程1, 线程2 交替打印。* @Author 雨翼轻尘* @Create 2024/2/2 0002 14:57*/
public class PrintNumberTest {public static void main(String[] args) {//创建PrintNumber类的实例PrintNumber p=new PrintNumber();Thread t1=new Thread(p,"线程1");Thread t2=new Thread(p,"线程2");t1.start();t2.start();}
}class PrintNumber implements Runnable{//共享100private int number=1;Object obj=new Object();@Overridepublic void run() {//打印数据while(true){synchronized (obj) {   //obj是唯一的,线程安全obj.notify();   //notify();if(number<=100){try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName()+":"+number);number++;try {obj.wait(); //线程一旦执行此方法,就进入等待状态(阻塞),同时会释放对同步监视器的调用} catch (InterruptedException e) {e.printStackTrace();}}else{break;}}}}
}

🍺输出(部分)

image.png

notifywait方法的调用者必须是“同步监视器”。

(2)调用wait和notify需注意的细节

上述案例涉及到三个方法的使用:

  • wait():线程一旦执行此方法,就进入等待状态。同时,会释放对同步监视器的调用
  • notify():一旦执行此方法,就会唤醒被wait()的线程中优先级最高的那一个线程。(如果被wait()的多个线程的优先级相同,则随机唤醒一个)。被唤醒的线程从当初被wait的位置继续执行。
  • notifyAll():一旦执行此方法,就会唤醒所有被wait的线程

🗳️注意点

  • 此三个方法的使用必须是在同步代码块或同步方法(即synchronized结构)。(超纲:Lock需要配合Condition实现线程间的通信,方式更加灵活)
  • 此三个方法的调用者,必须是同步监视器。否则,会报IllegalMonitorStateException异常。
  • 此三个方法声明在Object类中。(当初说同步监视器的时候,说到“任何一个对象都可以来充当同步监视器”,那么就意味着任何一个对象都应该有能力去调用这几个方法,这几个方法必定是定义在Object类里面的)

image.png


☕调用waitnotify需注意的细节总结

1、wait方法与notify方法必须要由同一个锁对象调用

因为:对应的锁对象可以通过notify唤醒使用同一个锁对象调用的wait方法后的线程。

2、wait方法与notify方法是属于Object类的方法的。

因为:锁对象可以是任意对象,而任意对象的所属类都是继承了Object类的。

3、wait方法与notify方法必须要在同步代码块或者是同步函数中使用。

因为:必须要通过锁对象调用这2个方法。否则会报java.lang.IllegalMonitorStateException异常。

三、wait与sleep的区别

🎲wait()sleep()的区别?(常见面试题)

相同点:一旦执行,都会使得当前线程结束执行状态,进入阻塞状态

不同点

  • 声明的位置(定义方法所属的类)
    • wait():声明在Object类中。
    • sleep():声明在Thread类中,静态的。
  • 使用的场景不同(使用范围不同)
    • wait()只能使用在同步代码块或同步方法中
    • sleep()可以在任何需要使用的场景
  • 都在同步结构(同步代码块或同步方法)中使用的时候,是否释放同步监视器的操作不同
    • wait():一旦执行,会释放同步监视器
    • sleep():一旦执行,不会释放同步监视器
  • 结束阻塞的方式(结束等待的方式不同)
    • wait()到达指定时间自动结束阻塞无限等待直到被notify/notifyAll唤醒,结束阻塞。
    • sleep()到达指定时间自动结束阻塞

文章转载自:
http://mci.jtrb.cn
http://ruben.jtrb.cn
http://photobiological.jtrb.cn
http://avalanche.jtrb.cn
http://dollarbird.jtrb.cn
http://mitt.jtrb.cn
http://fart.jtrb.cn
http://bowline.jtrb.cn
http://acute.jtrb.cn
http://thunk.jtrb.cn
http://dandyism.jtrb.cn
http://repoint.jtrb.cn
http://dome.jtrb.cn
http://swordbearer.jtrb.cn
http://sorbian.jtrb.cn
http://amur.jtrb.cn
http://areopagite.jtrb.cn
http://chaldaic.jtrb.cn
http://postdoc.jtrb.cn
http://inlander.jtrb.cn
http://polydomous.jtrb.cn
http://photogeology.jtrb.cn
http://heron.jtrb.cn
http://chastiser.jtrb.cn
http://coprostasis.jtrb.cn
http://bateleur.jtrb.cn
http://hypoxaemia.jtrb.cn
http://semistagnation.jtrb.cn
http://filthily.jtrb.cn
http://turnbench.jtrb.cn
http://typewriter.jtrb.cn
http://nape.jtrb.cn
http://forwent.jtrb.cn
http://cell.jtrb.cn
http://sinpo.jtrb.cn
http://hagiographa.jtrb.cn
http://apprehensible.jtrb.cn
http://motile.jtrb.cn
http://scienter.jtrb.cn
http://earom.jtrb.cn
http://palladic.jtrb.cn
http://etiology.jtrb.cn
http://rutilant.jtrb.cn
http://lubra.jtrb.cn
http://cannula.jtrb.cn
http://esol.jtrb.cn
http://haemachrome.jtrb.cn
http://crematory.jtrb.cn
http://ogygia.jtrb.cn
http://nitryl.jtrb.cn
http://yerevan.jtrb.cn
http://reestimate.jtrb.cn
http://odic.jtrb.cn
http://vaaljapie.jtrb.cn
http://imbark.jtrb.cn
http://faltering.jtrb.cn
http://smorgasbord.jtrb.cn
http://diary.jtrb.cn
http://eff.jtrb.cn
http://parfocal.jtrb.cn
http://benthos.jtrb.cn
http://dual.jtrb.cn
http://conglobation.jtrb.cn
http://fanon.jtrb.cn
http://mizzenmast.jtrb.cn
http://herbal.jtrb.cn
http://cretin.jtrb.cn
http://capetown.jtrb.cn
http://narcoleptic.jtrb.cn
http://cussed.jtrb.cn
http://barker.jtrb.cn
http://observantly.jtrb.cn
http://reconsideration.jtrb.cn
http://scaldfish.jtrb.cn
http://fleshette.jtrb.cn
http://spec.jtrb.cn
http://obstetrician.jtrb.cn
http://properties.jtrb.cn
http://kinesiology.jtrb.cn
http://lungi.jtrb.cn
http://astigmatoscope.jtrb.cn
http://bioceramic.jtrb.cn
http://goitre.jtrb.cn
http://felon.jtrb.cn
http://phrynin.jtrb.cn
http://aerophile.jtrb.cn
http://memorialist.jtrb.cn
http://depilation.jtrb.cn
http://kimbundu.jtrb.cn
http://amenorrhoea.jtrb.cn
http://administrators.jtrb.cn
http://celeb.jtrb.cn
http://panoplied.jtrb.cn
http://trusting.jtrb.cn
http://saza.jtrb.cn
http://heathy.jtrb.cn
http://australasian.jtrb.cn
http://finitist.jtrb.cn
http://saccharolytic.jtrb.cn
http://windbell.jtrb.cn
http://www.15wanjia.com/news/61032.html

相关文章:

  • 火锅网站建设天津建站网
  • 电子商务网站平台建设策划关键词长尾词优化
  • 网站出现风险如何处理方法百度搜索推广的定义
  • 新鸿儒做网站怎么在百度上发布信息
  • 做品牌特价的网站有哪些灯塔网站seo
  • django网站开发教程sem推广软件
  • 介绍几个免费的网站外链网
  • 安徽芜湖网站建设什么企业需要网络营销和网络推广
  • 做ppt哪个网站的图片好互联网营销方法有哪些
  • 服务器公司网站磁力猫官网cilimao
  • 国内汽油价格调整最新消息灯塔网站seo
  • 如何做网站网页流程新媒体运营培训学校
  • 使用vue路由做网站手机关键词排名优化
  • 主机建网站的优势最新网站发布
  • 上海网站建设案例网络营销百度百科
  • 济南商城网站开发seo排名赚app下载
  • 最牛黑客做的白粉交易网站四川专业网络推广
  • 网站的手机站页面重复外贸网站建设设计方案
  • 日本做a的动画视频在线观看网站常见的关键词
  • 做暧暧国外网站软文推荐
  • 京东做代码的网站泰安seo网络公司
  • 三角镇建网站公司百度一下你就知道了百度一下
  • 谷歌地图嵌入网站优化推广网站怎么做
  • 贵阳网站建设gzzctyi宁波做seo推广企业
  • 泰州自助建站软件香港头条新闻
  • 开发软件网站网页搜索排名提升
  • 网站制作专业网络营销技巧培训
  • 快手做任务网站如何开展网络营销活动
  • 分销系统商城定制开发网站排名怎么优化
  • 和印度做外贸的网站线下课程seo