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

网站图片速度厦门市建设管理协会网站首页

网站图片速度,厦门市建设管理协会网站首页,公益网站 html 模板,小兽wordpress官网目录 线程安全 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 概述 代码示例#xff1a; 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修饰的那么该类就叫做线程安全的类。保证同一时间只有一个线程能够进入 这种类的一个实例 的去修改数据进而保证了这个实例中的数据的安全不会同时被多个线程修改而变成脏数据。 操作集合的线程安全的类VectorHashtable操作字符串的线程安全的类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集合ListInteger nonThreadSafeList new ArrayListInteger();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 ListT synchronizedList(ListT list)          使用Collections.synchronizedList(list); 改造上述代码变成线程安全只需加入如下代码然后将多线程中操作的集合换成转换后的集合即可 //将List转换成线程安全的类ListInteger threadSafeList Collections.synchronizedList(nonThreadSafeList); 最终的执行结果如下执行多次结果一致。 与此类似的还有HashSet,LinkedList,HashMap等等非线程安全的类具体类型如下都可以通过Collections工具类转换为线程安全的 1.5 总结 在多线程中线程安全问题是不允许被出现的。所以我们在使用多线程时对于共享数据可以通过synchronized关键字和Lock锁来处理保证线程安全。 synchronized使用简单但灵活性较差而Lock是一个更灵活的同步方式可以实现更复杂的同步需求但需要手动管理锁的获取和释放。在实际开发中可以根据具体需求进行选择。
http://www.w-s-a.com/news/123536/

相关文章:

  • 广州视频网站建站公司网站 体系
  • 青浦门户网站网站推广烟台公司电话
  • 湖北荆门建设银行网站wordpress购物模板下载
  • 学ui+wordpress模板北京推广优化
  • 建分类网站得花多少钱深圳设计网站开发
  • 网站集群建设和网站集约化百度商桥怎么绑定网站
  • 青岛模板网站建设价格网络品牌网站建设
  • 网站建设的几大要素网站的做网站的公司
  • 怎么登陆自己的公司网站垂直电商网站建设
  • 温州微网站制作哪里有许昌网站建设哪家最好
  • 中国中小企业网站官网网页制作工具按其制作方式分 可以分为
  • 做资源下载网站违法吗河南企业做网站
  • 网站开发总体功能设计网站建设 北京昌平
  • 辽宁省高等级公路建设局网站书画院网站建设方案
  • 本地生活网站 源码重庆本地网站有哪些
  • 企业网站域名服务器国外html响应式网站
  • 东莞网站建设策划企业网站推广策划方法
  • 网站的图片怎么制作WordPress交互式网站
  • pc网站增加手机站什么专业学网页设计制作
  • 婚庆公司网站模板wordpress用什么框架
  • 高校网站建设的时效性长沙市网站建设
  • 合肥网站建设市场四川建设网官网住房和城乡厅官网官方
  • 天行健君子以自强不息网站建设江西网站做的好的企业文化
  • 建网站内容谷歌搜索引擎优化
  • 网站建设与管理案例教程第三版答案网站建设策划书范文六篇精选
  • 建设工程项目在哪个网站查询实时网站推广的最终目的是
  • 个人网站可以做淘客网站设置的参数
  • 自适应网站制作公司做室内设计通常上的网站
  • 网站建设项目采购公告建设网站公司建网页
  • 自己做网站怎么推广网站建设应该考虑哪些方面