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

政府网站建设过程中存在的问题网站优化检测

政府网站建设过程中存在的问题,网站优化检测,搜索引擎seo是什么,wordpress 支持js目录 一、线程安全 二、线程安全问题 三、线程安全 1.同步代码块 2.同步方法 3.Lock锁 3.1常用方法: 3.2 死锁 3.3 练习: 四、生产者和消费者(线程通信问题) 一、线程安全 如果有多个线程在同时运行,而这些…

目录

一、线程安全

二、线程安全问题

三、线程安全 

1.同步代码块 

2.同步方法

3.Lock锁

3.1常用方法:

 3.2 死锁

3.3 练习:

四、生产者和消费者(线程通信问题)


一、线程安全

如果有多个线程在同时运行,而这些线程可能会同时运行这些代码,程序每次运行的结果和单线程每次运行的结果是一样的,就是线程安全的,反之则是非线程安全的。

二、线程安全问题

现在有如下场景,电影院要卖票,我们模拟电影院的网上卖票过程。本次电影的座位共
100个(本场电影只能卖100张票)。我们来模拟电影院的售票窗口,实现多个窗口同时卖这
场电影票(多个窗口一起卖这100张票)。

售票窗口我们可以用线程来模拟。票数我们可以在 Runnable 的实现类中设定。

package thread;public class Demo {public static void main(String[] args) {SellTicket sellTicket=new SellTicket();Thread t1 = new Thread(sellTicket,"1号窗口");Thread t2 = new Thread(sellTicket,"2号窗口");Thread t3 = new Thread(sellTicket,"3号窗口");Thread t4 = new Thread(sellTicket,"4号窗口");Thread t5 = new Thread(sellTicket,"5号窗口");t1.start();t2.start();t3.start();t4.start();t5.start();}
}
class SellTicket implements Runnable {private int tickets=100;//总票数private Object object=new Object();//锁@Overridepublic void run() {//售票窗口一直开放while (true){//同步synchronized (object){//还有票if (tickets>0){try {Thread.sleep(100);//模拟出票} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println(Thread.currentThread().getName()+"正在出售第【"+tickets--+"】张票");}}}}
}

线程安全问题都是由全局变量及静态变量引起的, 若每个线程中对全局变量及静态变量只有读操作、没有写操作,一般来说,这个全局变量是线程安全的;若有多个线程同时执行写操作,一般都需要考虑线程同步,否则的话就可能影响线程安全。

安全问题出现的条件:

  • 多线程环境
  • 共享数据
  • 有多条语句操作共享数据 

 如果解决多线程安全问题?

  • 基本思想:让程序处在没有安全问题的环境中
  • 怎么解决:把多条语句操作共享数据的代码锁起来,使得在任何时刻只能有一个线程执行该代码
  • Java提供了同步的方式(synchronized)

三、线程安全 

当我们使用多个线程访问同一资源的时候,且多个线程中对资源有写的操作,就容易出现线程安全问题。要解决多线程并发访问同一资源的问题:也就是解决重复票和不存在票问题,Java中提供了同步机制来解决。 

也就是说一号窗口线程进入操作的时候,其他线程只能在外等着,一号窗口操作结束,其他代码(也包括一号窗口)才有机会去执行。也就是说在某个线程修改共享资源的时候,其他线程不能修改该资源,等待修改完毕同步之后,才能去抢夺CPU资源,完成对应的操作。

为了保证每个线程都能执行原子操作,Java提供了同步机制。

原子操作时不需要synchronized的,所谓原子操作是不能被线程调度机制打断的操作,这种操作一旦开始执行,就一直运行到结束,中间不会发生切换。

如果这个操作所处的层的更高层不能发现其内部实现和结构,那么这个操作就是一个原子操作。

原子操作可以是一个步骤,也可以是多个步骤,但是它的顺序不能被打乱,而且不能被切割只执行其中的一部分。

将整个操作视作一个整体是原子性的核心特征。

Java提供了三种同步机制:

  1. 同步代码块
  2. 同步方法
  3. 锁机制 

1.同步代码块 

synchronized关键字可以用于方法中的某个区块中,表示只对这个区块的资源实行互斥访问。

synchronized(同步锁){//同步的代码
}

同步锁:对象的同步锁只是一个概念,可以想象成在任何一个对象上标记了一个锁。

2.同步方法

使用synchronized修饰的方法,叫做同步方法,保证A线程执行该方法的时候,其他线程只能在方法外等着。

public synchronized void method(){// 可能出现安全问题的代码
}
或者
synchronized public void method(){//可能出现安全问题的代码
}

同步方法中的同步锁是什么?

对于实例方法,同步锁就是this。

对于static方法,同步锁就是方法所在类的字节码文件(类名.class)。

3.Lock锁

java.util.concurrent.locks.Lock机制提供了比synchronized代码块和synchronized方法更广泛的锁定操作,同步方法/同步代码块有的功能Lock都有,除此之外更强大,更体现面向对象。在JDK5引入了ReentrantLock,ReentrantLock重入锁,是实现Lock接口的一个类,也是在实际编程中总是用皮率很高的一个锁,支持重入性,表示能够对共享资源重复加锁,即当前线程获取该锁后再次获取不会被阻塞,支持公平锁和非公平锁两种方式。

3.1常用方法:

  • public void lock();   //加同步锁
  • public void unlock();  //释放同步锁

 3.2 死锁

  • 概述

 线程死锁是指由于两个或多个线程互相持有对方所需要的资源 ,导致这些线程处于等待状态,无法前往执行。

  • 什么情况下会产生死锁?
  1. 资源有限
  2. 同步嵌套 
package thread;public class Demo04 {public static void main(String[] args) {Object A = new Object();Object B = new Object();new Thread(()->{while (true){synchronized (A){synchronized (B){System.out.println("线程1");}}}}).start();new Thread(()->{while (true){synchronized (B){synchronized (A){System.out.println("线程2");}}}}).start();}
}

3.3 练习:


写5个线程对 i 进行 100次 加一操作,再写 5 个线程对 i 进行100次 减一操作,输出结果.

package thread;import java.util.concurrent.CountDownLatch;/*** 写5个线程对 i 进行 100次 加一操作,再写 5 个线程对 i 进行100次 减一操作,输出结果*/
public class Five {
//    public static int i=0;public static void main(String[] args) {//第一种
//        Thread[] t1 = new Thread[5];//加1的线程
//        Thread[] t2 = new Thread[5];//减1的线程
//
//        //加1的五个线程
//        for (int j = 0; j < 5; j++) {
//            t1[j]=new Thread(()->{
//                synchronized (Five.class){
//                    for (int k = 0; k < 1000; k++) {
//                        i++;
//                    }
//                }
//
//            });
//            t1[j].start();
//        }
//
//        //减1的五个线程
//        for (int j = 0; j < 5; j++) {
//            t2[j]=new Thread(()->{
//                synchronized (Five.class){
//                    for (int k = 0; k <1000; k++) {
//                        i--;
//                    }
//                }
//
//            });
//            t2[j].start();
//        }
//
//        for (int j = 0; j < 5; j++) {
//            try {
//                t1[j].join();
//                t2[j].join();
//            } catch (InterruptedException e) {
//                throw new RuntimeException(e);
//            }
//        }
//        System.out.println(Thread.currentThread().getName()+":"+i);Operate operate = new Operate();//线程计数CountDownLatch countDownLatch = new CountDownLatch(10);//定义Runnable对向执行加1操作Runnable addRun=()->{for (int j = 0; j < 100; j++) {operate.add();}//减少计数器的值countDownLatch.countDown();};//定义Runnable对向执行减1操作Runnable subRun=()->{for (int j = 0; j < 100; j++) {operate.sub();}countDownLatch.countDown();};for (int j = 0; j < 5; j++) {new Thread(addRun).start();}for (int j = 0; j < 5; j++) {new Thread(subRun).start();}try {countDownLatch.await();//等待线程数为0,说明十个线程都执行结束了} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println(operate.getI());}
}
class Operate{private int i=0;public void add(){synchronized (this){i++;}}public void sub(){synchronized (this){i--;}}public int getI(){return i;}
}

四、生产者和消费者(线程通信问题)

  • 概述 

生产者消费者模式是一种十分经典的多线程协作模式。

所谓生产者消费者问题,实际上主要包含了两类线程:

一种是生产者线程用于生产数据

一种是消费者线程用于消费数据

为了解耦生产者和消费者的关系,通常会采用共享的数据区域,就像是一个仓库。

生产者生产数据之后直接放到共享数据区中,并不需要关心消费者的行为

消费者只需要在共享数据区中去获取数据,并不需要关心生产者的行为。

调用wait()/notify()/notifyAll()方法时必须在同步方法/同步代码块中调用 

package thread;import java.time.LocalDateTime;/*** 线程间操作的必要性* 生产者消费者问题*/
public class Demo07 {public static void main(String[] args) {Cook cook = Cook.getCOOK();//厨师线程Maker maker = new Maker(cook, "邹厨师");//顾客Eater e1 = new Eater(cook,"浩哥");Eater e2 = new Eater(cook, "龙哥");Eater e3 = new Eater(cook, "王亮");maker.start();e1.start();e2.start();e3.start();}
}
//厨师类
class Cook{private String bread;//面包private static final Cook cook=new Cook();private Cook(){}public static Cook getCOOK() {return cook;}//同步  制作面包public synchronized void make(){if (bread!=null){try {System.out.println(Thread.currentThread().getName()+"睡了");wait();System.out.println(Thread.currentThread().getName()+"醒了");} catch (InterruptedException e) {throw new RuntimeException(e);}}//制作面包的过程try {Thread.sleep(3000);} catch (InterruptedException e) {throw new RuntimeException(e);}bread= LocalDateTime.now().toString();notify();System.out.println(Thread.currentThread().getName()+"做了一个面包"+bread);}//吃public synchronized void eat(){if (bread==null){try {System.out.println(Thread.currentThread().getName()+"睡了");wait();System.out.println(Thread.currentThread().getName()+"醒了");} catch (InterruptedException e) {throw new RuntimeException(e);}}else {try {//吃面包的过程Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println(Thread.currentThread().getName()+"吃了"+bread);bread=null;notifyAll();//确保把厨师唤醒}}
}
//顾客类---主要是吃
class Eater extends Thread{Cook cook;public Eater(Cook cook,String name) {super(name);this.cook = cook;}@Overridepublic void run() {while (true){cook.eat();}}
}
//制作面包的类
class Maker extends Thread{Cook cook;public Maker(Cook cook,String name){super(name);this.cook=cook;}@Overridepublic void run() {while (true){cook.make();}}
}
http://www.hkea.cn/news/912322/

相关文章:

  • 做公务员题的网站口红的推广软文
  • 福州网站建设 联系yanktcn 04上海百网优seo优化公司
  • 网站备案号如何获得网站建设营销推广
  • 物流网站开发公司西安 做网站
  • 商务信息网站怎么做网络视频营销策略有哪些
  • 社交做的最好的网站怎么开发一个网站
  • 教育品牌网站建设百度搜索推广和信息流推广
  • 虎门专业做网站对网络营销的认识有哪些
  • 投资理财培训网站建设抖音引流推广一个30元
  • 做景观设施的网站网络营销推广要求
  • 携程网站建设进度及实施过程网络营销的缺点及建议
  • 石家庄网站建设哪家专业中国联通腾讯
  • 能访问各种网站的浏览器百度一下网页搜索
  • 自己做网站花多少钱雅虎搜索
  • 哈尔滨招标信息网网站推广优化排名教程
  • 个人可以建论坛网站吗福清网络营销
  • 济南做网站优化价格百度推广网站一年多少钱
  • 做网上商城网站哪家好杭州seo靠谱
  • 做营销网站制作关键词优化课程
  • 网站移动终端建设口碑营销成功案例
  • 美国做试管婴儿 网站推广普通话宣传语
  • 网站备案信息查询系统软文发布平台媒体
  • 泊头哪给做网站的好制作网页的教程
  • 漳州建设银行网站首页在百度上打广告找谁
  • 网站免费建站k网络营销策划方案书
  • 网站建设类公网店推广的作用
  • 安平做网站除了百度指数还有哪些指数
  • 做网站公司 蓝纤科技知乎怎么申请关键词推广
  • 临沂免费做网站发表文章的平台有哪些
  • 网站推广的方式包括哪些广西网站建设制作