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

做国内电影网站赚钱不社群营销平台有哪些

做国内电影网站赚钱不,社群营销平台有哪些,jquery网页设计成品,福田庆三整过的明星目录 线程安全 1.1 概述 1.2 案例分析 1.3 解决线程安全问题 1.3.1 使用synchronized关键字 1.3.1.1 同步代码块 1.3.1.2 同步方法 1.3.2 使用Lock锁 1.3.2.1 概述 代码示例: 1.4 线程安全的类 1.4.1 非线程安全集合转换成线程安全集合 1.5 总结 …

目录

线程安全

1.1 概述 

1.2 案例分析 

1.3 解决线程安全问题

1.3.1 使用synchronized关键字

1.3.1.1 同步代码块 

1.3.1.2 同步方法

1.3.2 使用Lock锁

1.3.2.1 概述 

代码示例:

1.4 线程安全的类

1.4.1 非线程安全集合转换成线程安全集合 

1.5 总结


线程安全

1.1 概述 

        指如果有多个线程在同时运行,而这些线程可能会同时运行某段代码,程序每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全。

1.2 案例分析 

那什么情况下会导致【线程不安全】呢?看如下案例:

假设:有三家电影院,卖票形式分别为以下A、B、C三种。

思考:哪一种卖票形式会出现问题呢?

  • 第1种:开一个窗口,卖100张票,不会出现问题,单线程程序不存在线程安全问题。
  • 第2种:开三个窗口,但是每个窗口票的号码不冲突,也不会出现问题,属于线程安全。
  • 第3种:开三个窗口,但是每个窗口票的号码一样。如果1,2,3三个窗口访问同一张票,那进入的结果和返回的结果很有可能不一致。这就出现了线程安全问题。

结论:

        买票出现了线程安全问题,可能会出现重复的票和不存在的票,但是线程安全问题是不允许出现的。 

1.3 解决线程安全问题

那怎么解决线程安全问题呢?

        我们可以让一个线程在访问共享数据的时候,无论是否失去了CPU的执行权,让其他的线程只能等待,等待当前线程买完票,其他线程在进行买票。保证同时只有一个线程在买票

1.3.1 使用synchronized关键字

        在Java中,synchronized是一个关键字,用于控制多个线程对 对象或方法 的访问。当一个代码块被标记为synchronized时,只允许一个线程在同一时间执行该代码块。这样做是为了防止并发访问和潜在的数据损坏或不一致。该关键字可以使用在同步代码块或者同步方法用来解决线程安全问题。

1.3.1.1 同步代码块 

         一个同步代码块一次只允许一个线程进入,并确保它完成执行后其他线程才能进入。这是通过使用与同步代码块关联的对象的内在锁(或监视器)来实现的。

格式:
       synchronized(锁对象){
           可能会出现线程安全问题的代码(访问了共享数据的代码)
       }

        

注意事项:

        1.同步代码块中的锁对象,可以使用任意的对象。

        2.必须保证多个线程使用的锁对象是同一个。

        3.锁对象作用:把同步代码块锁住,只让一个线程在同步代码块中执行。

代码示例: 

RunnableImpl.java:多线程的实现类

package com.zhy.multiplethread;public class RunnableImpl implements Runnable{/*** 共享票数*/private int ticket = 10;/*** 设置线程任务:卖票*/@Overridepublic void run() {//使用死循环,让卖票操作重复执行while (true){//同步代码块,保证每次只有一个线程占用锁对象synchronized (this){//当存在余票时,进行卖票操作if (ticket > 0){//为了表示卖票需要时间,暂停10毫秒try {Thread.sleep(10);}catch (InterruptedException e){e.printStackTrace();}System.out.println(Thread.currentThread().getName() + " 正在卖第 " + ticket + "张票");ticket--;}}//出了同步代码块,归还锁对象,供线程重新抢占}}
}

TestThread.java:线程测试类

package com.zhy.multiplethread;public class TestThread {public static void main(String[] args) {RunnableImpl impl = new RunnableImpl();Thread t1 = new Thread(impl);Thread t2 = new Thread(impl);Thread t3 = new Thread(impl);//开启3个线程一起抢夺CPU的执行权,谁抢到谁执行t1.start();t2.start();t3.start();}
}

输出结果:多个线程共同抢占CPU进行卖票操作,不会出现线程安全问题。

1.3.1.2 同步方法

        当一个方法被声明为synchronized时,即使有多个线程同时访问该方法,也只允许一个线程执行。在这种情况下使用的锁是调用该方法的对象实例。  

格式:
        修饰符 synchronized 返回值类型 方法名(参数列表){
                可能会出现线程安全问题的代码(访问了共享数据的代码)
        }

        

使用步骤:

        1.把访问了共享数据的代码抽取出来,放到一个方法中。

        2.在方法上添加synchronized修饰符

代码示例:

RunnableImpl.java:多线程的实现类 

package com.zhy.multiplethread;public class RunnableImpl implements Runnable{/*** 共享票数*/private int ticket = 10;/*** 设置线程任务:卖票*/@Overridepublic void run() {//使用死循环,让卖票操作重复执行while (true){payTicket();}}/*** 同步方法:卖票*/public synchronized void payTicket(){//当存在余票时,进行卖票操作if (ticket > 0){//为了表示卖票需要时间,暂停10毫秒try {Thread.sleep(10);}catch (InterruptedException e){e.printStackTrace();}System.out.println(Thread.currentThread().getName() + " 正在卖第 " + ticket + "张票");ticket--;}}
}

结论:

        通过使用synchronized关键字,我们可以确保在多线程环境中共享资源的安全访问。

1.3.2 使用Lock锁

1.3.2.1 概述 

        java.util.concurrent.locks.Lock接口:实现提供了比使用synchronized方法和语句可获得的更广泛的锁定操作。 

Lock接口中的方法:
       void lock():获取锁
       void unlock():释放锁

        

实现类:

        java.util.concurrent.locks.ReentrantLock implements Lock接口

        

使用步骤:

        1.在成员位置创建一个ReentrantLock对象。

        2.在可能会出现安全问题的代码前调用Lock接口中的方法lock获取锁。

        3.在可能会出现安全问题的代码后调用Lock接口中的方法unlock释放锁。一般放在finally里面执行。

代码示例:

RunnableImpl.java:多线程实现类

package com.zhy.multiplethread;import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;public class RunnableImpl implements Runnable{/*** 共享票数*/private int ticket = 10;Lock l = new ReentrantLock();/*** 设置线程任务:卖票*/@Overridepublic void run() {//使用死循环,让卖票操作重复执行while (true){//获取锁:当存在余票时,进行卖票操作l.lock();try {if (ticket > 0) {//为了表示卖票需要时间,暂停10毫秒Thread.sleep(10);System.out.println(Thread.currentThread().getName() + " 正在卖第 " + ticket + "张票");ticket--;}}catch (InterruptedException e){e.printStackTrace();}finally {//释放锁:为了避免忘记释放或者出现异常,造成死锁,该操作放在finally中执行l.unlock();}}}
}

结论:

        同步保证了只能有一个线程在同步中执行共享数据,保证率安全,但是程序频繁的判断锁、获取锁、释放锁、程序的效率会降低。

1.4 线程安全的类

        如果一个类,所有的方法都是有synchronized修饰的,那么该类就叫做线程安全的类。保证同一时间,只有一个线程能够进入 这种类的一个实例 的去修改数据,进而保证了这个实例中的数据的安全,不会同时被多个线程修改而变成脏数据。

  • 操作集合的线程安全的类:Vector,Hashtable
  • 操作字符串的线程安全的类:StringBuffer

1.4.1 非线程安全集合转换成线程安全集合 

        ArrayList是非线程安全的,如果多个线程可以同时进入一个ArrayList对象的add/remove方法。那会造成什么后果呢,我们先看一个案例。 

场景:

        定义一个List集合,初始化5个元素。定义一个增加线程(往集合的头部持续插入1000个元素)和减少线程(从集合的头部持续移除1000个元素)同时操作该集合,我们最终想要的效果是:增加和减少的次数一致,最终集合内的元素仍然是初始化的元素。

代码示例:

package com.zhy.multiplethread;import com.zhy.thread.RunnableImpl;import java.util.ArrayList;
import java.util.List;public class TestThread {public static void main(String[] args) {//初始化List集合List<Integer> nonThreadSafeList = new ArrayList<Integer>();for (int i = 0; i < 5; i++){nonThreadSafeList.add(i + 3);}System.out.println("初始化List集合:" + nonThreadSafeList);//验证:使用两个线程同时往集合中插入1000个元素,在删除1000个元素int n = 1000;Thread[] addThreads = new Thread[n];Thread[] reduceThreads = new Thread[n];//将所有 增加线程 加入到addThreads数组中for (int i = 0; i < n; i++){Thread addThread = new Thread(){@Overridepublic void run() {nonThreadSafeList.add(0,1);try {//暂停1000毫秒,给其他线程抢占CPU的时间Thread.sleep(1000);}catch (InterruptedException e){e.printStackTrace();}}};addThread.start();addThreads[i] = addThread;}//将所有 减少线程 加入到reduceThreads数组中for (int i = 0; i < n; i++){Thread reduceThread = new Thread(new RunnableImpl(){@Overridepublic void run() {if (nonThreadSafeList.size() > 0){nonThreadSafeList.remove(0);}try {//暂停1000毫秒,给其他线程抢占CPU的时间Thread.sleep(1000);}catch (InterruptedException e){e.printStackTrace();}}});reduceThread.start();reduceThreads[i] = reduceThread;}//等待所有增加线程执行完成for (Thread addThread : addThreads){try {//将 增加线程 加入到主线程中addThread.join();}catch (InterruptedException e){e.printStackTrace();}}//等待所有 减少线程 执行完成for (Thread reduceThread : reduceThreads){try {//将 减少线程 加入到主线程中reduceThread.join();}catch (InterruptedException e){e.printStackTrace();}}//所有增加线程 和 减少线程 执行完毕后,List集合中的数据:正确应该为初始数据System.out.println("所有增加线程 和 减少线程 执行完毕后,List集合中的数据:" + nonThreadSafeList);}
}

输出结果:

        使用非线程安全的集合进行多线程处理,很显然最终的结果并不是我们想要的,出现了null的元素,且集合内的元素也不是初始化的元素。 

注:并不是每一次执行都会出现错误的结果,多执行几次,会发现执行结果并不一致。 

那如何把非线程安全的集合转换成线程安全的呢?  

        以ArrayList为例,使用Collections工具类中的synchronizedList,可以把ArrayList转换为线程安全的List。 

源码:

        public static <T> List<T> synchronizedList(List<T> list) ;

        

使用:Collections.synchronizedList(list);

        改造上述代码,变成线程安全,只需加入如下代码,然后将多线程中操作的集合换成转换后的集合即可:

        //将List转换成线程安全的类List<Integer> threadSafeList = Collections.synchronizedList(nonThreadSafeList);

 最终的执行结果如下,执行多次,结果一致。


        与此类似的,还有HashSet,LinkedList,HashMap等等非线程安全的类,具体类型如下,都可以通过Collections工具类转换为线程安全的


1.5 总结

        在多线程中,线程安全问题是不允许被出现的。所以我们在使用多线程时,对于共享数据,可以通过synchronized关键字和Lock锁来处理,保证线程安全。 synchronized使用简单但灵活性较差;而Lock是一个更灵活的同步方式,可以实现更复杂的同步需求,但需要手动管理锁的获取和释放。在实际开发中,可以根据具体需求进行选择。

http://www.ds6.com.cn/news/11436.html

相关文章:

  • 中山制作网站的公司成人职业技术培训学校
  • 网站营销的重要价值韶山seo快速排名
  • wordpress定制主题保定百度推广优化排名
  • 二维码制作方法优化大师免费下载安装
  • 怎样可以提升自己的网站如何在百度发视频推广
  • 给网站首页图片做外网超链接_为什么会弹出一个服务器登录窗口互联网营销方案
  • 郑州网站建设最便宜关键词seo排名优化软件
  • wordPress主题模板站网络推广培训班
  • 公明网站建设怎么做李飞seo
  • 新增网站推广百度关键词查询工具
  • 如何做学校网站软文广告有哪些
  • 网站原创文章来源近期发生的重大新闻
  • 装修设计公司取名宁波seo网络推广报价
  • 网页设计怎么赚钱优优群排名优化软件
  • 贵阳白云区疫情最新情况今天aso苹果关键词优化
  • 做平台网站外包多少钱啊俄罗斯搜索引擎yandex
  • wordpress插件 速度seo搜索优化工程师招聘
  • 企业建设网站应如何申请seo怎样
  • 如何提升网站点击量网页制作图片
  • 网站做接口怎么做长沙全网推广
  • 织梦网站管理系统百度怎么免费推广自己的产品
  • 代表b2c的平台是北京seo邢云涛
  • 黑色企业网站广西南宁做网站的公司
  • 乐清做网站公司百度搜索流量查询
  • 江苏威达建设有限公司网站关键词排名点击软件推荐
  • JAVA做的小型网站有哪些搜索引擎营销是什么
  • python做的网站如何打开app推广全国代理加盟
  • 做个简单的公司网站要多少钱推广资源网
  • wordpress换主题链接百度seo站长工具
  • 怎样看网站的建设时间seo模板建站