java线程安全的方法

今日,嗨壳技术分享网小编分享java线程安全的方法 相关内容,内容如下。

  java中为什么说,String是线程安全的?

  String是不可变类,所以是线程安全的。

  1、所有不可变类都是线程安全的,线程安全的类不一定是不可变类,如StringBuffer是可变类,靠锁实现线程安全。

  2、StringBuffer方法上都加了synchronized,StringBuilder没有,StringBuilder在多线程情况下是会出现问题,但是线程安全线程非安全指的是你业务环境需要线程安全考虑不考虑。多并发网络编程这块会考虑这些。

  在Java语言中,线程是一种特殊的对象,它必须由Thread类或其子(孙)类来创建。

  通常有两种方法来创建线程:

  其一,使用型构为Thread(Runnable)的构造子将一个实现了Runnable接口的对象包装成一个线程。

  其二,从Thread类派生出子类并重写run方法,使用该子类创建的对象即为线程。

  值得注意的是Thread类已经实现了Runnable接口,因此,任何一个线程均有它的run方法,而run方法中包含了线程所要运行的代码。线程的活动由一组方法来控制。Java语言支持多个线程的同时执行,并提供多线程之间的同步机制(关键字为synchronized)。

  如何创建线程?如何保证线程安全?

  创建线程的方式一:继承Thread类(由于Java单继承的特性,这种方式用的比较少)

  步骤:

  1、继承Thread类,然后重写run方法

  请点击输入图片描述

  2、创建子类对象,然后调用start()方法来启动线程

  请点击输入图片描述

  我们可以看到这边现在只创建了一个线程,那么如果要创建多个线程要怎么做呢?通过继承Thread的方式创建线程,想要创建多个不同的线程就要先创建多个不同的继承Thread的类,然后再根据上面的步骤1,2来创建线程,这显然有些麻烦,为了展示多线程,我们先在上面的线程中增加一个主线程,也就是main方法中执行的线程。如下:

  请点击输入图片描述

  创建线程的方式二:实现Runnable接口(Java可以实现多个接口,这种方式常用)

  步骤:

  1、创建一个类实现Runnable接口,然后重写run方法

  请点击输入图片描述

  2、创建实现类对象、代理类对象,然后代理类对象调用start()方法启动线程

  用实现Runnable接口的方式,实现多线程:

  《模拟抢票系统》,代码如下:

  线程调用了start()方法,并不意味着立即执行,而是到就绪状态,等待cpu的调度,所以每次执行的结果都是不一样的。

java线程安全的方法

  创建线程的方式三:实现java.util.concurrent并发包下的Callable接口(进阶版,初学者做个了解)

  步骤:

  1、创建一个类实现Callable接口,然后重写call()方法

  (和run方法不一样的是,call方法可以有返回值,并且可以抛出异常)

  2、创建Callable的实现类对象–》创建执行服务–》提交执行服务得到Future对象–》获取结果–》停止服务

  Java Swing开发中的线程安全

  SwingAPI的设计目标是强大 灵活和易用 非凡地 我们希望能让程序员们方便地建立新的Swing组件 不论是从头开始还是通过扩展我们所提供的一些组件 出于这个目的 我们不要求Swing组件支持多线程访问 相反 我们向组件发送请求并在单一线程中执行请求 本文讨论线程和Swing组件 目的不仅是为了帮助你以线程安全的方式使用SwingAPI 而且解释了我们为什么会选择现在这样的线程方案 本文包括以下内容

  单线程规则 Swing线程在同一时刻仅能被一个线程所访问 一般来说 这个线程是事件派发线程 规则的例外 有些操作保证是线程安全的 事件分发 假如你需要从事件处理或绘制代码以外的地方访问UI 那么你可以使用SwingUtilities类的invokeLater要求在事件派发线程中执行某些代码 这个方法会立即返回 不会等待代码执行完毕 invokeAndWait行为与invokeLater类似 除了这个方法会等待代码执行完毕 一般地 你可以用invokeLater来代替这个方法 下面是一些使用这几个API的例子 请同时参阅《TheJavaTutorial》中的 BINGOexample 尤其是以下几个类 CardWindow ControlPane Player和OverallStatusPane

  使用invokeLater方法你可以从任何线程调用invokeLater方法以请求事件派发线程运行特定代码 你必须把要运行的代码放到一个Runnable对象的run方法中 并将此Runnable对象设为invokeLater的参数 invokeLater方法会立即返回 不等待事件派发线程执行指定代码 这是一个使用invokeLater方法的例子

java线程安全的方法

  RunnabledoWorkRunnable=newRunnable };

  SwingUtilities invokeLater;使用invokeAndWait方法invokeAndWait方法和invokeLater方法很相似 除了invokeAndWait方法会等事件派发线程执行了指定代码才返回 在可能的情况下 你应该尽量用invokeLater来代替invokeAndWait 假如你真的要使用invokeAndWait 请确保调用invokeAndWait的线程不会在调用期间持有任何其他线程可能需要的锁

  这是一个使用invokeAndWait的例子

  voidshowHelloThereDialogthrowsException }; SwingUtilities invokeAndWait; }

  类似地 假设一个线程需要对GUI的状态进行存取 比如文本域的内容 它的代码可能类似这样

  voidprintTextField throwsException }; SwingUtilities invokeAndWait; System out println;}

  假如你能避免使用线程 最好这样做 线程可能难于使用 并使得程序的debug更困难 一般来说 对于严格意义下的GUI工作 线程是不必要的 比如对组件属性的更新 不管怎么说 有时候线程是必要的 下列情况是使用线程的一些典型情况 执行一项费时的任务而不必将事件派发线程锁定 例子包括执行大量计算的情况 会导致大量类被装载的情况 和为网络或磁盘I/O而阻塞的情况 重复地执行一项操作 通常在两次操作间间隔一个预定的时间周期 要等待来自客户的消息 你可以使用两个类来帮助你实现线程 SwingWorker 创建一个后台线程来执行费时的操作 Timer 创建一个线程来执行或多次执行某些代码 在两次执行间间隔用户定义的延迟 使用SwingWorker类SwingWorker类在SwingWorker java中实现 这个类并不包含在Java的任何发行版中 所以你必须单独下载它 SwingWorker类做了所有实现一个后台线程所需的肮脏工作 虽然许多程序都不需要后台线程 后台线程在执行费时的操作时仍然是很有用的 它能提高程序的性能观感

  SwingWorkersanexampleofusingSwingWorker 要使用SwingWorker类 你首先要实现它的一个子类 在子类中 你必须实现construct方法还包含你的长时间操作 当你实例化SwingWorker的子类时 SwingWorker创建一个线程但并不启动它 你要调用你的SwingWorker对象的start方法来启动线程 然后start方法会调用你的construct方法 当你需要construct方法返回的对象时 可以调用SwingWorker类的get方法 这是一个使用SwingWorker类的例子

  //在main方法中 finalSwingWorkerworker=newSwingWorker }; worker start; //在动作事件处理方法中 JOptionPane showMessageDialog)

  当程序的main方法调用start方法 SwingWorker启动一个新的线程来实例化ExpensiveDialogComponent main方法还构造了由一个窗口和一个按钮组成的GUI 当用户点击按钮 程序将阻塞 假如必要 阻塞到ExpensiveDialogComponent创建完成 然后程序显示一个包含ExpensiveDialogComponent的模式对话框 你可以在MyApplication java找到整个程序 使用Timer类Timer类通过一个ActionListener来执行或多次执行一项操作 你创建定时器的时候可以指定操作执行的频率 并且你可以指定定时器的动作事件的监听者 启动定时器后 动作监听者的actionPerformed方法会被调用来执行操作 定时器动作监听者定义的actionPerformed方法将在事件派发线程中调用 这意味着你不必在其中使用invokeLater方法 这是一个使用Timer类来实现动画循环的例子

  publicclassAnimatorApplicationTimer extendsJFrameimplementsActionListener publicvoidstartAnimationelse } publicvoidstopAnimation publicvoidactionPerformed }

  在一个线程中执行所有的用户界面代码有这样一些优点 组件开发者不必对线程编程有深入的理解 像ViewPoint和Trestle这类工具包中的所有组件都必须完全支持多线程访问 使得扩展非常困难 尤其对不精通线程编程的开发者来说 最近的一些工具包如SubArctic和IFC 都采用和Swing类似的设计 事件以可预知的次序派发 invokeLater排队的runnable对象从鼠标和键盘事件 定时器事件 绘制请求的同一个队列派发 在一些组件完全支持多线程访问的工具包中 组件的改变被变化无常的线程调度程序穿插到事件处理过程中 这使得全面测试变得困难甚至不可能 更低的代价 尝试小心锁住临界区的工具包要花费实足的时间和空间在锁的治理上 每当工具包中调用某个可能在客户代码中实现的方法时 工具包都要保存它的状态并释放所有锁 以便客户代码能在必要时获得锁 当控制权交回到工具包 工具包又必须重新抓住它的锁并恢复状态 所有应用程序都不得不负担这一代价 即使大多数应用程序并不需要对GUI的并发访问 这是的SubArcticJavaToolkit的对在工具包中支持多线程访问的问题的描述 我们的基本信条是 当设计和建造多线程应用程序 尤其是那些包括GUI组件的应用程序时 必须保证极端小心 线程的使用可能会很有欺骗性 在许多情况下 它们表现得能够极好的简化编成 使得设计 专注于单一任务的简单自治实体 成为可能 在一些情况下它们的确简化了设计和编码 然而 在几乎所有的情况下 它们都使得调试 测试和维护的困难大大增加甚至成为不可能 无论大多数程序员所受的练习 他们的经验和实践 还是我们用来帮助自己的工具 都不是能够用来对付非决定论的 例如 全面测试在bug依靠于时间时是几乎不可能的 尤其对于Java来说 一个程序要运行在许多不同类型的机器的操作系统平台上 并且每个程序都必须在抢先和非抢先式调度下都能正常工作 由于这些固有的困难 我们力劝你三思是否绝对有使用线程的必要 尽管如此 有些情况下使用线程是必要的 所以subArctic提供了一个线程安全的访问机制

  lishixinzhi/Article/program/Java/gj/201311/27616

  如何确保Java线程安全?

  在Java中可以有很多方法来保证线程安全——同步,使用原子类(atomicconcurrentclasses),实现并发锁,使用volatile关键字,使用不变类和线程安全类。

  Java中如何保证线程安全性

  并发(concurrency)一个并不陌生的词,简单来说,就是cpu在同一时刻执行多个任务。

  而Java并发则由多线程实现的。

  在jvm的世界里,线程就像不相干的平行空间,串行在虚拟机中。(当然这是比较笼统的说法,线程之间是可以交互的,他们也不一定是串行。)

  多线程的存在就是压榨cpu,提高程序性能,还能减少一定的设计复杂度(用现实的时间思维设计程序)。

  这么说来似乎线程就是传说中的银弹了,可事实告诉我们真正的银弹并不存在。

  多线程会引出很多难以避免的问题, 如死锁,脏数据,线程管理的额外开销,等等。更大大增加了程序设计的复杂度。

  但他的优点依旧不可替代。

  死锁和脏数据就是典型的线程安全问题。

  简单来说,线程安全就是: 在多线程环境中,能永远保证程序的正确性。

  只有存在共享数据时才需要考虑线程安全问题。

  java内存区域:

  其中, 方法区和堆就是主要的线程共享区域。那么就是说共享对象只可能是类的属性域或静态域。

  了解了线程安全问题的一些基本概念后, 我们就来说说如何解决线程安全问题。我们来从一个简单的servlet示例来分析:

  public class ReqCounterServlet extends HttpServlet{    private int count = 0;

  public void doGet(HttpServletRequest request,

  HttpServletResponse response) throws IOException, ServletException {

  count++;

  System.out.print(“当前已达到的请求数为” + count);

  }

  public void doPost(HttpServletRequest request,

  HttpServletResponse response) throws IOException, ServletException {        // ignore    }

  }

  1. 了解业务场景的线程模型

  这里的线程模型指的是: 在该业务场景下, 可能出现的线程调用实况。

  众所周知,Servlet是被设计为单实例,在请求进入tomcat后,由Connector建立连接,再讲请求分发给内部线程池中的Processor,

  此时Servlet就处于一个多线程环境。即如果存在几个请求同时访问某个servlet,就可能会有几个线程同时访问该servlet对象。如图:

  线程模型,如果简单的话,就在脑海模拟一下就好了,复杂的话就可以用纸笔或其他工具画出来。

  2. 找出共享对象

  这里的共享对象就很明显就是ReqCounterServlet。

  3. 分析共享对象的不变性条件

  不变性条件,这个名词是在契约式编程的概念中的。不变性条件保证类的状态在任何功能被执行后都保持在一个可接受的状态。

  这里可以引申出, 不可变对象是线程安全的。(因为不可变对象就没有不变性条件)

  不变性条件则主要由对可变状态的修改与访问构成。

  这里的servlet很简单, 不变性条件大致可以归纳为: 每次请求进入时count计数必须加一,且计数必须正确。

  在复杂的业务中, 类的不变性条件往往很难考虑周全。设计的世界是险恶的,只能小心谨慎,用测量去证明,最大程度地减少错误出现的几率。

  4. 用特定的策略解决线程安全问题。

  如何解决的确是该流程的重点。目前分三种方式解决:

  第一种,修改线程模型。即不在线程之间共享该状态变量。一般这个改动比较大,需要量力而行。

  第二种,将对象变为不可变对象。有时候实现不了。

  第三种,就比较通用了,在访问状态变量时使用同步。 synchronized和Lock都可以实现同步。简单点说,就是在你修改或访问可变状态时加锁,独占对象,让其他线程进不来。

  这也算是一种线程隔离的办法。(这种方式也有不少缺点,比如说死锁,性能问题等等)

  其实有一种更好的办法,就是设计线程安全类。《代码大全》就有提过,问题解决得越早,花费的代价就越小。

  是的,在设计时,就考虑线程安全问题会容易的多。

  首先考虑该类是否会存在于多线程环境。如果不是,则不考虑线程安全。

  然后考虑该类是否能设计为不可变对象,或者事实不可变对象。如果是,则不考虑线程安全

  最后,根据流程来设计线程安全类。

  设计线程安全类流程:

  1、找出构成对象状态的所有变量。

  2、找出约束状态变量的不变性条件。

  3、建立对象状态的并发访问管理策略。

java线程安全的方法

  有两种常用的并发访问管理策略:

  1、java监视器模式。  一直使用某一对象的锁来保护某状态。

  2、线程安全委托。  将类的线程安全性委托给某个或多个线程安全的状态变量。(注意多个时,这些变量必须是彼此独立,且不存在相关联的不变性条件。)

以上是嗨壳技术分享网(www.heikehao.com)小编对“ java线程安全的方法 ”的详细解答,希望能够帮助到大家。

原创文章,作者:java,如若转载,请注明出处:https://www.heikehao.com/667.html

(0)
javajava
上一篇 2020年1月3日
下一篇 2020年1月3日

相关推荐

  • 包含md5解密java代码的词条

    今日,嗨壳技术分享网小编分享包含md5解密java代码的词条 相关内容,内容如下。   求MD5加密解密代码   我简单说下吧,加密就是存进数据库的时候变成MD5存进去,解密,就是…

    2021年12月16日
  • 微信java开发,微信java代码

    今日,嗨壳技术分享网小编分享微信java开发,微信java代码 相关内容,内容如下。   微信小程序的开发需要掌握哪些开发语言?   1、以微信小程序的开发语言为例,用到的语言有:…

    2020年4月12日
  • 包含javalist遍历的词条

    关于包含javalist遍历的词条话题,今日,嗨壳技术分享网小编抽出大半天的时间整理一些包含javalist遍历的词条内容,让我们一起了解一些技术吧!   今天给各位分享javal…

    2022年10月1日
  • java获取当前日期的方法

    1、System.currentTimeMillis() 获取标准时间可以通过System.currentTimeMillis()方法获取,此方法不受时区影响,得到的结果是时间戳格…

    java 2023年12月8日
  • 原型模式javaclone

    原型模式javaclone 大家并不陌生,借来给大家详细说说吧!   java设计模式prototype模式   按我的理解,原型引入的根本原因就是在于它可以利用一个原型对象(在这…

    2020年6月7日
  • 怎么清理java注册表,java注册表在哪

    关于怎么清理java注册表,java注册表在哪话题,今日,嗨壳技术分享网小编抽出大半天的时间整理一些怎么清理java注册表,java注册表在哪内容,让我们一起了解一些技术吧!   …

    2020年3月31日
  • java方法参数默认值是什么

    基本数据类型: byte 默认值为0 short 默认值为0 int 默认值为0 long 默认值为0L float 默认值为0.0f double 默认值为0.0d char 默…

    java 2023年12月9日
  • 实战java高并发程序设计视频,java高并发编程详解多线程与架构设计

    今天,嗨壳技术分享网给大家整理一些实战java高并发程序设计视频,java高并发编程详解多线程与架构设计内容。   零基础学java应该从哪里开始?   1、我给出的ava学习路线…

    2021年2月28日
  • 身份证校验java

    身份证校验java   java字符串操作,验证输入的身份证合法与否   使用java语言实现一个身份证号码转换的程序:把15位号码转换为18位的号码功能要求:判断输入身份证号位数…

    2020年7月1日
  • java调用dll怎么查看dll日志

    本文介绍java使用jni调用c、c++编写生成的dll文件或so文件中的接口方法实现过程。 1. 编写java含有本地方法的测试类。 package com.gh;   publ…

    java 2023年12月11日

网上怎么找黑客帮忙多少钱

怎么网上找到的黑客?黑客的收费标准是什么呢?找黑客一般费用是多少?


找黑客帮忙一般要多少钱

黑客服务的价格范围很广,主要取决于服务的类型和难度。根据提供的信息如下:


1.攻击服务:


攻击范围:这包括了通过扫描入侵、种植木马等方式对他人计算机实施非法控制,并利用被控制的计算机对网站、App等服务器发起攻击


。1

2.特定账户的售价:


账户信息:如垂钓者、而勒索软件,显示市场对特定黑客工具的需求和价格波动。

3.攻击工具:

“RIG”攻击工具包的租用费用,提供了不同时长的选择。

4.远程访问木马(RAT)的价格:

相比去年有所下降,显示出市场价格的波动。

5.DDOS攻击的报价:

DDOS攻击服务按不同时长定价选择。

黑客服务的价格因服务类型、难度、以及市场需求的不同而有很大的差异。这些价格反映了黑客服务市场的复杂性和多样性,同时也提醒人们网络安全的重要性。