精华内容
下载资源
问答
  • servlet是web三大组件之一.是最重要组件 servlet是什么? 可以干什么? Servlet接口HttpServlet ... servlet是线程安全的吗? 不是的话,解决方案是什么?   1.servlet是什么? 可以干什么? Servlet是...

    servlet是web三大组件之一.是最重要组件

    1. servlet是什么? 可以干什么?
    2. Servlet接口与HttpServlet
    3. servlet的生命周期
    4. servlet的常见配置
    5. Servlet如何接收数据,响应数据?
    6. JSP是什么? 为什么要有JSP?
    7. servlet是线程安全的吗? 不是的话,解决方案是什么?

     

    1.servlet是什么? 可以干什么?

    Servlet是web应用中的java程序,它可以对用户的请求进行处理,并做出响应.

     

    2.当然Servlet从狭义上讲它是一个接口,里面规定了一些api.广义上讲指实现servlet接口的类.我们一般说的都是广义上的.

    public interface Servlet {
    
    public void init(ServletConfig config) throws ServletException;
    
    public ServletConfig getServletConfig();
    
    public void service(ServletRequest req, ServletResponse res)throws ServletException, IOException;
    
    public String getServletInfo();
    
        public void destroy();
    
    }

    上面的这个servlet接口,要实现的方法太多,而且有些内容重复.tomcat就帮我们写好了一个很好的实现类 HttpServlet,我们只要继承它就可以.

    public class TestServlet extends HttpServlet {
    
    private static final long serialVersionUID = 1L;
    
        public TestServlet() {
            super();      
        }
    
    public void init(ServletConfig config) throws ServletException {
    //服务器启动后,客户端第一次访问时执行
    }
    
    public void destroy() {
    //服务器关闭时执行
    }
    
    protected void service(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
    //每访问一次,就会调用一次
    //属于web层业务逻辑
    }
    }
    
    

    上面的代码,简单提及到servlet的生命周期,下一节仔细讲一下.

    当然如果,我们不需要初始化等与业务逻辑无关的方法,那么只覆盖父类的 doGet()  doPost() 就可以.也就是eclipse中默认创建servlet中的方法

    public class HelloServlet extends HttpServlet {
    
    private static final long serialVersionUID = 1L;
        public HelloServlet() {
            super();
        }
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
    
    throws ServletException, IOException {
    
    response.getWriter().append("Served at: ").append(request.getContextPath());
    
    }
    
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
    doGet(request, response);
    }
    }
    
    

     

     

    3.servlet的生命周期

    Servlet的生命周期,看下图

    1. 当有客户向服务器发出请求后,服务器通过映射文件(web.xml或注解),找到servlet.对它进行编译并执行init(),就是初始化操作.
    2. 服务器创建servlet是以单例模式创建的.所以上图中,thread A和thread B会访问同一个servlet.这样在减少资源使用的情况下,同时可能造成线程安全问题.(这个问题会在文章后面细说)
    3. 服务器会帮我们创建 http的request和response.帮助我们获取客户端信息,更方便的响应客户请求
    4. 有了servlet对象,request和response之后,就可以执行service()了.service()中有会调用service层中的方法,以完成整个逻辑.
    5. 最后,在服务器关闭时.JVM帮我们回收servlet对象.

     

    下面这个图,是我访问百度,通过chrome浏览器可以看到的一部分http请求与响应.当然这些信息都是可以通过,service()中request得到的

     

    4.servlet的常见配置

    Eclipse中 2.5 版本之前,都是使用web.xml来配置的.之后采用注解方式配置.当然两者各有利弊.在xml中配置,对于需要时不时修改一下的配置是合适的.而注解方式更适合,配置完成后基本不做修改的配置.这里不细讲了.感兴趣可以自行百度w3School

     

    5.Servlet如何接收数据,响应数据?

    在tomcat中,会把用户的http请求内容,处理成一个request对象.同时创建一个response对象用于响应用户.

    至于具体是如何创建的request的对象.我并没有看过具体的源码.在这里仅仅做一个简单的推测.在tomcat接收到http请求,这个请求会把请求行,请求头,请求体里的内容一段一段的解析.做一些复杂的字符串处理.然后再将各种信息整合分类.

    Ajax:往往用于异步传输数据,请求没有变化,响应时,不需要请求转发或者重定向.一般是把数据转换为JSON字符串,然后传给客户端.记得服务器响应时,要设置好response.setContentType("application/json;charset=utf-8")

     

    6.JSP是什么? 为什么要有JSP?

    JSP是一种特殊的servlet.每个JSP都对应一个java对象.具体的代码可以打开tomcat.以我的为例,该目录下可以看到具体的代码

    C:\Tomcat 8.0\webapps\work\Catalina\localhost\mycrm\org\apache\jsp

     

    我们可以看到每个jsp都对应着一个.class和.java文件.打开.java文件之后

    public final class top_jsp extends org.apache.jasper.runtime.HttpJspBase

        implements org.apache.jasper.runtime.JspSourceDependent {}

    里面有类似与servlet的init,destroy,service方法.在service()中,可以看到

     

    从这里可以引出,为什么要有JSP?

    在没有JSP 之前,人们只能想上图那样,一行一行的将html的代码输出.这是一件很枯燥且丧心病狂的一件事.导致了很多人接受不了.没办法,sun就推出了jsp.

    以前说在JSP中内嵌java代码,后来才知道,是在java中嵌入html代码.当然了,JSP的表达方式和html非常相似.而且还可以动态生成代码.方便多了.而且之后也推出了想JSTL,EL,更加使JSP中的Java代码变得少了.

    另外:JSP有9个内置对象.为什么能有呢?因为它在service()中创建了9个对象.就当然可以在JSP页面中使用了.

     

    7.servlet是线程安全的吗? 不是的话,解决方案是什么?

    在 Web 应用程序中,一个 Servlet 在一个时刻可能被多个用户同时访问。这时 Web 容器将为每个用户创建一个线程来执行 Servlet。如果 Servlet 不涉及共享资源的问题,不必关心多线程问题。但如果 Servlet 需要共享资源,需要保证 Servlet 是线程安全的。

    也就是说:servlet在有共享资源下,很可能出现线程安全问题!

    我知道的解决方法有3种

    1. 不使用可变的共享变量.可以使用final修饰的变量.但是一般的成员变量,就不能使用了.这从根本上解决了问题.但是呢,没有了共享变量,在方法中可能要多次创建相同的对象.造成资源的浪费.
    2. 使用synchronized 来对共享变量的操作进行加锁.这样会大大降低并发性.
    3. 继承单线程接口,这个根本不可能使用.单线程的话,就可以当单机游戏玩了.

     

    当然,现在的框架都解决了servlet的线程安全问题.那个就更复杂了.一言半语讲不清的.

    才疏学浅,若有不当之处,请指出,共同学习!

     

    参考资源

    http://www.runoob.com/servlet/

     

    展开全文
  • GIL的定义问答

    2019-06-05 21:22:00
    解释以下问题1、什么是GIL是Cpython中全局解释器锁,是一种互斥锁,是为了防止多个本地线程同一时间执行python字节码2、有了GIL会对单进程下多个线程造成什么样影响造成多线程不能并行执行3、为什么要有GIL...
    """
    1、整理GIL解释器锁,解释以下问题
    1、什么是GIL
    是Cpython中的全局解释器锁,是一种互斥锁,是为了防止多个本地线程
    同一时间执行python字节码
    2、有了GIL会对单进程下的多个线程造成什么样的影响
    造成多线程不能并行执行
    3、为什么要有GIL
    因为Cpython的内存管理是非线程安全的,然而GIL尤其存在的必要性可以防止
    多个本地线程同一时间执行python字节码,同时已经存在很多代码需要依赖这个锁了
    4、GIL与自定义互斥锁的区别,多个线程争抢GIL与自定义互斥锁的过程分析
    他们都是互斥锁,但GIL是加在python解释器上的,只能锁住解释器内部的资源,但无法锁住我们
    自己开启的资源、自己开启的共享资源还需要自己锁
    但例如申请内存,保存数据等等就不需要我们程序员自己考虑了,GIL已经搞定了
    5、什么时候用python的多线程,什么时候用多进程,为什么?
    如果是IO密集时使用多线程如果时计算密集时使用多进程
    """
    """
    2、进程池与线程池
    1、池的用途,为何要用它
    池时一个容器,线程池就是装线程的容器,
    可以使用它来管理线程的开启与销毁
    自动分配任务给空闲的线程
    可以控制线程开启的数量,保证系统的稳定
    2、池子里什么时候装进程什么时候装线程?
    """

    转载于:https://www.cnblogs.com/huanghongzheng/p/10982006.html

    展开全文
  • Radspec是以太坊动态表达式的安全解释器。 这使智能联系人开发人员可以向最终用户显示经过改进功能文档,而不会。 Radspec定义了自己语法结构并解析了自己AST,而不是直接评估不受信任JavaScript。 产品...
  • 价值密度足够高的大数据是支撑互联网产品向用户提供友好服务的利器,用户产生数据和企业处理数据时时刻刻都在并行;...对于大数据,Gartner给出了这样的定义:大数据是需要新处理模式才能具有更强的决策力、洞察发现
  • Java 线程安全与锁优化

    千次阅读 2019-05-25 14:56:53
    线程安全经常会被各种行业大佬或者面试官大佬挂在嘴边,如何找到一个通俗易懂一点的方式解释线程安全呢,伟大的砖家给出了答案:如果一个对象可以安全的被多个对象使用,那它就是线程安全的。是的,这种回答非常的...

    什么是线程安全?

    线程安全经常会被各种行业大佬或者面试官大佬挂在嘴边,如何找到一个通俗易懂一点的方式解释线程安全呢,伟大的砖家给出了答案:如果一个对象可以安全的被多个对象使用,那它就是线程安全的。是的,这种回答非常的巧妙精彩…巧妙到你无法怼它是错误的…但是也无法从中找到任何有用信息…

    众多定义中,《Java Concurrency In Practice》的作者Brian Goetz对线程安全有一个比较恰当的定义:

    当多个线程访问一个对象时,如果不用考虑这些线程在运行时环境下的调度和交替执行,也不需要进行额外的同步,或者在调用方进行任何其他的协调操作,调用这个对象的行为都可以获得正确的结果,那么这个对象就是线程安全哒~~~

     

    是不是还有点云里雾里?没关系,我们来具体的分一下,看看Java语言中操作共享数据的5中情况,然后结合这些情况来看Java中的线程安全。

    1. 不可变

    这种方式是最安全最简单粗暴的。但是很不幸也是适用范围最少的。成也不可变,败也不可变。

    如何实现不可变,很简单用final关键字修饰的对象就是不可变的,比如String,我们调用它的substring,trim等各种方法但是它原始的值还是不变的,以至于我们不得不用一个新对象去接收返回结果。

     

    2. 绝对线程安全

    绝对线程安全也就是达到上面那个Brian大佬讲的,在任何情况下随意调用都是线程安全的,他讲的还是很严格的,Java中口口声称自己是线程安全的类,大多数不是绝对线程安全的,比如Vector,具体不做解释,可自行百度,反正sun已经不建议使用Vector了,效率比ArrayList低就不说了,还是一样得做额外的同步。所以,要想绝对线程安全,我们还是得求助synchronized大哥,或者用ReentrantLock。

     

    3. 相对线程安全

    相对线程安全就是我们通常讲的线程安全,比如Vector,Hashtable, 里面的方法,用了synchronized关键字修饰过,是相对想成安全的。

     

    4. 线程兼容

    我们一般说一个类或方法不是线程安全的,基本八九不离十也就是这种情况了。比如HashMap,ArrayList等,我们接触的最多,简单粗暴高效,但是只是相对线程安全,也就是无人争抢的时候不会出错,一旦发生争抢还是得做额外的同步措施。

     

    5. 线程对立

    这是最可怕的一种情况,就是说无论怎么抢救都要往阎王殿跑的八头马拉不回的,根本无法在多线程环境中并发使用的代码。这种排斥多线的代码Java中很少见,但是还是有,比如Thread类的suspend和resume方法,如果连个线程同时持有一个对象,一个尝试终止,另一个尝试去恢复,那么很容易就死锁了,所以伟大的伞公司也废弃了这两个方法。

     

    线程安全的实现方法

    1. 互斥同步

    通常用的比较多的就是加入synchronized关键字来修饰需要同步的方法或代码块,以及需要上锁的对象。当然用ReentrantLock也可以达到同样的效果,或者更高级的体验。

     

    Synchronized关键字和ReentrantLock类:

    在Java多线程同步机制中,ReentrantLock可以达到和synchronized关键字同样的效果,不仅如此,它在扩展功能上也更加强大,比如具有嗅探锁定,多路分支通知等功能,而且在使用上也比synchronized更加灵活。

    ReentrantLock支持查询等待队列的状态,支持手动上锁解锁,支持等待/通知模式,支持多对象监视器,另外它的派生类ReentrantReadWriteLock还支持读写锁(即共享锁/排它锁)。

     

    ReentrantLock有以下三项优势:

    1)等待可中断:当持有的线程长期占着茅坑不拉屎(不释放锁)的时候,正在等待的线程可以放弃等待,改为处理其他事情,可中断特性对处理时间较长的同步块尤为重要。

    2)公平锁:指多个线程在等待同一个锁的时候,必须按照申请的时间顺序来依次获得锁(先来先得),而非公平锁则不能保证这一点,synchronized是非公平的,ReentrantLock在默认情况下也是非公平的,需要通过bool类型的构造参数设置。

    3)绑定多个条件:指一个ReentrantLock对象可以同时绑定多个Condition对象,而在synchronized中,如果要做到多个对象监视器,必须多加几个synchronized关键字,而ReentrantLock中不需要这样傻,只需要每次都newCondition()方法优雅地解决。

     

    性能优势:以前ReentrantLock在多线程环境下是比synchronized要稳定高效许多的,但是随着JDK版本的不断改进,synchronized也能保持一个很高效稳定的状态,JDK的意思肯定还是想多推广使用synchronized,毕竟如此简单粗暴,因此,如果不需要考虑以上三点ReentrantLock所具备的优势,则优先使用synchronized。

     

    2. 非阻塞同步

    互斥同步的主要问题就是进行线程阻塞和唤醒所带来的性能问题,因此这种同步也称为:阻塞同步(Blocking Synchronization)。 从处理问题的方式上来说,互斥同步属于一种悲观的并发策略(悲观锁),即:总是认为只要不进行正确的同步措施(比如加锁)就肯定会出现问题,无论共享数据是否真的会出现竞争,它都要进行加锁(这里讨论的是概念模型,实际上虚拟机会优化掉很大一部分不必要的加锁)、用户态和心态的转换、维护锁计数器和检查是否有被阻塞的线程需要唤醒等操作。随着指令集的发展,我们有了另一个选择:基于冲突检测的乐观并发策略(乐观锁),即:新进行操作,如果没有其他线程争用共享数据,那操作就成功了,如果共享数据有争用,产生了冲突,那就再采取其他的补偿措施(最常见的补偿措施就是不断的重试,知道成功为止),这种乐观的并发策略的很多实现都不需要把线程挂起,因此这种同步操作称为非阻塞同步(Non-Blocking Synchronization)。

     

    再简单总结下悲观锁和乐观锁:

    悲观锁(阻塞式同步):总是任务只要不做同步措施,就肯定会出现问题,无论是否发生争抢共享数据情况。(总是认为只要不戴tt就一定会怀孕,无论对方是否在安全期

    乐观锁(非阻塞式同步):先执行操作,如果没有其他线程争抢共享数据,操作就成功;如果有,采取一定的不就措施,最常见的就是不断重试。(直接开干,没怀孕就算是爽到了,如果怀孕再去医院补救

     

    乐观并发策略的前景是令人心动的,但是它依赖指令集的发展(老的指令集不支持),因为我们需要操作和冲突检测这两个步骤具有原子性,考什么来保证原子性呢,如果此时再使用互斥同步来保证原子性就失去意义了,所以我们只能依赖硬件的发展来完成这件事情。硬件需要保证一个从语义上来讲需要多次操作的行为只需要通过一条指令就能完成,这类指令常用的有:

    测试并设置

    获取并添加

    交换

    比较并交换

    加载链接/条件存储

    有了这些指令的支持,我们才可以做到非阻塞式同步,也就是必要同步的那一块是硬件代替了,硬件的执行速度和软件程序的执行速度谁高谁低非常的明显。

     

    3. 无同步方案

    保证线程安全不一定是需要同步的。

    可重入代码:

    可以在执行代码的任何时刻中断它,转而去执行另一段代码,在控制权返回后原来的程序不会发生任何错误,因此所以可重入的代码都是线程安全的,但并非所有线程安全的代码都是可重入的。

    可重入代码有这些特征:不依赖堆上的数据,用到的状态量都由参数传入,不调用非可重入方法等。

    是不是有点懵,举个具体的例子,我们常用的方法,只要它不依赖某些成员变量,或者依赖的这些全局变量是不发生改变的(单例或final),无论任何时候,我们只需要传入相应的参数并且都能得到一致的返回结果,那么这个方法就是可重入的。这也就是为什么我们要谨慎使用全局变量,并且尽量用方法的参数去代替全局变量,因为后者更加的线程安全。

     

    线程本地存储:

    ThreadLocal在前面的《线程间的通信》博客里面也讲到了,它就是维护线程内的全局变量的一个对象,这样根本不会发生多个线程争抢的情况,因为它只属于某一个线程。

    线程本地存储并不止这一个案例,现在很多流行的Web框架也屡见不鲜,比如Spring MVC中,会将每一个请求都创建一个线程,将请求的数据放在这个线程中。

     

    锁优化

    为了在线程之间更高效地共享数据,JDK大佬们尽心竭力的进行了很多优化,高效并发是JDK1.5 到JDK1.6的一个很重要的改进。

    1. 自旋锁与自适应自旋锁

    前面我们提到了,互斥同步对性能的最大影响是阻塞的实现,挂起线程和恢复线程的操作都需要转入内核态中完成,这些操作给系统的并发性能带来了很大的压力。虚拟机的大佬们注意到,许多共享数据的锁定状态只会持续很短的时间,在这么短的时间去挂起和恢复线程有点大炮打蚊子的赶脚,于是乎,他们想到一个办法 – 让后面的线程稍等一下,状态依旧是Runable态,不用发生改变,等这个线程执行完,也不用恢复了直接就可以执行。读到这你肯定会说,这么小儿科我也能想到,看吧,你离大神不远矣!是的,就是这么随意,接下来,JDK大佬要解决的就是怎么让后面的线程喝喝茶“稍等一会”的问题了?于是,自旋锁就出来了,从字面也很好理解---线程自己进入一个循环自己空转。当然也不是瞎转悠,JDK大佬给他们设置了一个默认的次数:10次(你可以修改JVM参数调整这个数字),也就是10次over了,它就又跳出来争抢共享数据,如果发现那个占着茅坑的线程走了,它就蹲过来了,如果发现别人还没走,就只能乖乖挂起来了(进入等待队列)。

    JDK1.6中又引入了自适应自旋锁,自适应就意味着自旋的时间/次数不在固定,而是由前一次在同一个锁上的自旋时间以及锁的拥有者的状态来动态决定的。比方说,如果之前碰到有个人占了茅坑一小会,那么它就自己在旁边晃悠一下,比如10次;如果之前碰到别人占了好一会,那么它可能晃悠100圈;如果更变态的之前碰到别人占着茅坑不拉屎,在里面玩游戏,那么它干脆就懒得在旁边晃悠了,乖乖跑到厕所外等待。

    自适应自旋锁肯定比普通的自旋锁更“聪明”,相信,随着虚拟机的发展,以后它会越来越聪明。

     

    2. 锁消除

    锁消除是指虚拟机即时编译器在运行时,对一些在代码上要求同步,但被检测到不可能出现共享数据竞争的锁进行消除。

     

    3. 锁粗化

    前面两种都是伟大的虚拟机大侠自动帮我们这些小白解决的,但虚拟机也不是救世主,有些情况需要我们自己在设计代码的时候考虑的,具体场景应具体对待。

    通常映像中,我们应该是认为锁的范围越小越好,这样可以使多个线程异步执行的范围就越大,效率应该就越高。但是如果一系列的操作都对同一个对象进行反复的加锁/解锁,甚至更变态的加锁的操作是在循环体中进行的,那即时没有线程竞争,频繁的进行互斥同步也会带来很多不必要的性能消耗。

    所以,反而言之,如果对同一个对象的同步操作比较多,那么我们是否可以考虑将这些操作放到一个同步块或同步方法里面去呢?

     

    4. 锁细化

    和上面那个家伙不同,如果对同一个对象操作比较少,只需要很小的一块地方需要同步,那么久尽量去细化,也就是被同步的代码块或方法尽量的简短。

     

     

    参考:

    《深入理解Java虚拟机》周志明著

    《Java多线程核心技术》高洪岩著

     

     

     

    展开全文
  • 背景和背景:在法国和魁北克,职业健康与安全(OHS)已成为国家首要任务。 尽管这两个社会组织略有不同,但预防措施是相同,立法要求即使在中小型企业中,也必须将选择改善OHS方法减少为书面形式。 预防是...
  • 线程不安全:说完了线程安全,线程不安全的问题就很好解释,如果多线程并发执行时会产生不同的结果,则该线程就是不安全的。 线程安全产生的原因:大多是因为对全局变量和静态变量的操作 常见的线程不安全的函数 ...

    线程安全

    基本定义
    线程安全:简单来说线程安全就是多个线程并发同一段代码时,不会出现不同的结果,我们就可以说该线程是安全的;
    线程不安全:说完了线程安全,线程不安全的问题就很好解释,如果多线程并发执行时会产生不同的结果,则该线程就是不安全的。
    线程安全产生的原因:大多是因为对全局变量和静态变量的操作
    常见的线程不安全的函数
    (1)不保护共享变量的函数
    (2)函数状态随着被调用,状态发生变化的函数
    (3)返回指向静态变量指针的函数
    (4)调用线程不安全函数的函数
    常见的线程安全的情况
    (1)每个线程对全局变量或者静态变量只有读取的权限,而没有写入的权限,一般来说这些线程是安全的;
    (2)类或者接口对于线程来说都是原子操作;
    (3)多个线程之间的切换不会导致该接口的执行结果存在二义性;
    执行代码:
    #include<stdio.h>
    #include<pthread.h>
    int value=0;
    void* func(void* arg){
            int i=0;
            while(i<10000){
                    int tmp=value;
                    value=i;
                    printf("value is %d\n",value);
                    value=tmp+1;
                    i++;
            }
    }
    int main()
    {
            pthread_t id1,id2;
            pthread_create(&id1,NULL,func,NULL);
            pthread_create(&id2,NULL,func,NULL);
    
            pthread_join(id1,NULL);
            pthread_join(id2,NULL);
            printf("value is %d\n",value);
            return 0;
    }

    可重入函数

    基本定义
    重入:同一个函数被不同的执行流调用,当前一个流程还没有执行完,就有其他的进程已经再次调用(执行流之间的相互嵌套执行);
    可重入:多个执行流反复执行一个代码,其结果不会发生改变,通常访问的都是各自的私有栈资源;
    不可重入:多个执行流反复执行一段代码时,其结果会发生改变;
    可重入函数:当一个执行流因为异常或者被内核切换而中断正在执行的函数而转为另外一个执行流时,当后者的执行流对同一个函数的操作并不影响前一个执行流恢复后执行函数产生的结果;
    不可重入函数:当程序运行到某一个函数的时候,可能因为硬件中断或者异常而使得在用户正在执行的代码暂时终端转而进入你内核,这个时候如有一个信号需要被处理,而处理的这个信号的时候又会重新调用刚才中断的函数,如果函数内部有一个全局变量需要被操作,那么,当信号处理完成之后重新返回用户态恢复中断函数的上下文再次继续执行的时候,对同一个全局变量的操作结果可能就会发生改变而并不如我们预期的那样,这样的函数被称为不可重入函数。例如在进行链表的插入时,插入函数访问一个全局链表,有可能因为重入而造成错乱。
    可重入函数满足条件
    (1)不使用全局变量或静态变量;
    (2)不使用用malloc或者new开辟出的空间;
    (3)不调用不可重入函数;
    (4)不返回静态或全局数据,所有数据都有函数的调用者提供;
    (5)使用本地数据,或者通过制作全局数据的本地拷贝来保护全局数据;
    不可重入函数符合以下条件之一
    (1)调用了malloc/free函数,因为malloc函数是用全局链表来管理堆的。
    (2)调用了标准I/O库函数,标准I/O库的很多实现都以不可重入的方式使用全局数据结构
    (3)可重入体内使用了静态的数据结构。
    可重入函数分类
    (1)显式可重入函数
    如果所有函数的参数都是传值传递的(没有指针),并且所有的数据引用都是本地的自动栈变量(也就是说没有引用静态或全局变量),那么函数就是显示可重入的,也就是说不管如何调用,我们都可断言它是可重入的。
    (2)隐式可重入函数
    可重入函数中的一些参数是引用传递(使用了指针),也就是说,在调用线程小心地传递指向非共享数据的指针时,它才是可重入的。
    可重入函数可以有多余一个任务并发使用,而不必担心数据错误,相反,不可重入函数不能由超过一个任务所共享,除非能确保函数的互斥(或者使用信号量,或者在 代码的关键部分禁用中断)。可重入函数可以在任意时刻被中断,稍后再继续运行,不会丢失数据,可重入函数要么使用本地变量,要么在使用全局变量时保护自己 的数据。
    执行代码:
    #include<stdio.h>
    #include<signal.h>
    int value=0;
    void fun(){
            int i=0;
            while(i++<5){
                    value++;
                    printf("value is %d\n",value);
                    sleep(1);
            }
    }
    int main()
    {
            signal(2,fun);
            fun();
            printf("the value is %d\n",value);
            return 0;
    }



    展开全文
  • 本文旨在探索和解释软件定义...通过本报告,读者能够清楚认识到企业IaaS 所面临的安全挑战(基于共享责任模型),原有IaaS 访问控制传统网络安全工具结合产生的安全问题,以及软件定义边界在各种场景中解决之道。
  • 第一部分解释了“好密码”一词含义。 它包含一个密码定义和多个密码安全定义。 尽管听起来并不多,但这是我在那里学到最重要事情之一。 这很重要,因为密码旨在保护您免受定义明确攻击,并且容易受到...
  • 线程安全不是一个非真即假命题 7月份我们并发专家 Brian Goetz 将 Hashtable 和 Vector 类描述为“有条件线程... 在本月 Java 理论实践中解释的,尽量在 Javadoc 中对类线程安全性进行归类是非常
  • 本书从整体和微观的角度解释了分析和理解系统安全的必要步骤,定义了风险驱动的安全、保护机制和如何最好地部署这些机制,提出了以一种可用的和对用户友好的方式来实施安全的方式方法。所有主题都是电子商务,但它们...
  • 术语定义 术语 英文 解释 哈希算法 hash algorithm 是一种将任意内容输入转换成相同长度输出加密方式,其输出被称为哈希值。  哈希表 hash table 根据设定哈希函数...
  • #defineconst联系:都可以用来定义常量区别:1. const常量有数据类型,而宏常量没有数据类型。编译器可以对前者进行类型安全检查。而对后者只进行字符替换,没有类型安全检查,并且在字符替换可能会产生意料不到...
  • 该标准的目标为IT安全管理方面提供保障,而不是解决方法,为IT安全负责的组织中的那些单独的个体应该能在报告中不断调整内容以满足特定的需要,技术报告的主要...提供几个能解释IT安全的模型 提供IT安全管理的一般向导
  • 从今天开始每天给大家分享一下Java面试中被问到问题,共同学习共同进步,奥利给! 面向对象三大特性及...封装意义就是增强类信息隐藏模块化,提高安全性。封装主要作用也是对外部隐藏具体实现细节,增加
  • PKCS#7中将数字信封作为术语进行定义,而在正文中对进行了如下解释:数字信封包含被加密内容和被加密用于加密该内容密钥。虽然经常使用接收方公钥来加密“加密密钥”,但这并不是必须,也可以使用发送方和...
  • 是建立的SSL/TLS协议之上的,最简单的,我们在使用浏览器访问某个网站是,网址有http和https,我们有一种简单的认知,https要比http安全,这其实就是https使用了SSL/TLS协议,百科中的定义如下: SSL(Secure ...
  • jbpm 异常处理与安全问题

    千次阅读 2005-06-23 15:57:00
    下面来学习jbpm高级话题部分(包括异常处理、安全、运行jbpm测试例子)高级话题--异常处理Jbpm给java 编程语言增加了状态管理。Jbpm座右铭是:“做一件事就把它做好”。因此我们不想重复那些已经在java语言自身...
  • JAVA名词定义

    2008-12-29 09:55:10
    JAVA定义:Java是一种简单的,面向对象的,分布式的,解释型的,健壮安全的,结构中立的,可移植的,性能优异、多线程的动态语言。   Java的主要特性:   1、Java语言是简单的。Java语言的语法C语言和C++语言很...
  • 这项审查表明,没有关于弹性工程的普遍认可的定义。 但是它涉及一个集体方面,是多因素,多层次和多维的; 四个关键原则(预期,响应,学习和监控)相关联并取得成功。 想象的工作执行的工作之间的差距是一个...
  • Shell 作为弱类型动态解释型语言,不像 C++、JAVA 语言编程时需要事先声明变量,Shell给一个变量赋值,实际上就是定义了变量。在 Linux 支持所有 shell 中,都可以用赋值符号(=)为变量赋值,Shell 变量为弱类型...
  • 1、通过java内存模型解释线程的安全与数据同步问题 java内存模型定义了线程和主内存之间抽象关系: 共享变量存储于主内存中,每个线程都能访问 每个线程都有私有工作内存,用于存储共享变量副本 线程不能...
  • 我经常阅读有关“如果对象是不可变的,则它是线程安全的”的文章。 实际上,我从未找到过一篇让我相信不变的意味着线程安全的文章。 即使是Brian Goetz的Java Concurrency in ... 因此,我将尝试定义不变性及其...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 666
精华内容 266
关键字:

安全的定义与解释