java 线程---成员变量与局部变量
关于成员变量与局部变量:
如果一个变量是成员变量,那么多个线程对同一个对象的成员变量进行操作时,他们对该成员变量是彼此影响的(也就是说一个线程对成员变量的改变会影响到另一个线程) 。
如果一个变量是局部变量,那么每个线程都会有一个该局部变量的拷贝,一个线程对该局部变量的改变不会影响到其他的线程。
实例:
Servlet容器为了响应多个用户同时访问一个Servlet的HTTP请求,通常会为每个请求分配一个工作线程,这些工作线程并发执行同一个Servlet(即Servlet是单实例的)的service()方法。此时可能发生多线程对同一数据进行访问的情况。
- public class Hello extends HttpServlet{
- private String name;
- public void doPost(HttpServletRequest request,HttpServletResponse response)
- throws ServletException,java.io.IOException{
- response.setContentType("text/html;charset=UTF-8");
- name = (String)request.getParameter("name"); //接收参数
- PrintWriter out = response.getWriter();
- out.println("<html><head><title>test</title></head><body>");
- out.println("你好"+name);
- out.println("</body></html>");
- out.close();
- }
- }
如果多线程并发访问,会访问同一个实例变量,则会共用name,而出现用户得到数据不一致的现象。
解决办法:
1.将name设置为局部变量。
- public class Hello extends HttpServlet{
- public void doPost(HttpServletRequest request,HttpServletResponse response)
- throws ServletException,java.io.IOException{
- response.setContentType("text/html;charset=UTF-8");
- String name = (String)request.getParameter("name"); //接收参数
- ...
- }
- }
每当一个线程执行doPost()时,在线程的堆栈中就会创建name这个局部变量,当线程执行完该方法,局部变量就结束生命周期。如果多个线程同时执行该方法,那么每个线程都拥有自己的局部变量。
2.使用Java同步机制对多线程同步
- public class Hello extends HttpServlet{
- private String name;
- public void doPost(HttpServletRequest request,HttpServletResponse response)
- throws ServletException,java.io.IOException{
- response.setContentType("text/html;charset=UTF-8");
- synchronized(this){
- name = (String)request.getParameter("name"); //接收参数
- ...
- }
- ...
- }
- }
这样可确保在任意一时刻,只允许有一个工作线程执行doPost()中的同步代码块。只有当这个工作线程退出同步代码块时,其他工作线程才允许执行同步代码块。这使得任意时刻不会有两个线程同时操纵同一个实例变量,从而避免并发问题。
3.实现被废弃的SingleThreadModel接口
public class Hello extends HttpServlet implements
SingleThreadModel{
...
}
如果实现此接口,则Servlet容器实现可以采用以下两种方式之一来运行Servlet:
1)在任意一时刻,只允许有一个工作线程执行Servlet的service()方法。如果有多个用户同时请求访问该Servlet,那么这些客户请求被
放入等待队列,容器会依次响应等待队列中的每个客户请求。这种实现方式实际上禁止了多个客户端对同一个Servlet的并发访问。
2)Servlet容器为每个Servlet创建一个对象池,在这个池中存放了同一个Servlet类的多个实例。如果有多个用户同时请求访问该
Servlet,Servlet容器会为每个请求分配一个工作线程,并且从对象池中取出一个空闲的Servlet实例,把它分配给工作线程。每个工作线程
执行自己的Servlet实例的service()方法。这种实现方式表面上允许客户端对同一个Servlet并发访问,但实际上不同客户端访问的是同一
个Servlet类的不同实例。
如果实例变量需要共享,用以进行计算,这种方法并不能有效的避免并发问题。
java 线程---成员变量与局部变量的更多相关文章
- java中成员变量,局部变量,静态变量的辨析
转自百度:https://baijiahao.baidu.com/s?id=1625360816541592483&wfr=spider&for=pc 1.java中成员变量,局部变量 ...
- Java基础-成员变量与局部变量
Java基础-成员变量与局部变量 1.什么是成员变量与局部变量? public class Student { String name; int high; public void stu ...
- Java中成员变量和局部变量的区别
java面向对象过程中,最基本的两类变量就是成员变量和局部变量 成员变量是写在类中并且写在方法外部,一般写在每个类的头部,用于初始化或者方法操作,作用域是整个类被实例化到被销毁,中间变量都可以被外部方 ...
- [ 转载 ] Java中成员变量 和局部变量
java语言支持的变量类型 类变量:独立于方法之外的变量,用 static 修饰. 局部变量:类的方法中的变量. 实例变量(全局变量):独立于方法之外的变量,不过没有 static 修饰. publi ...
- java中成员变量和局部变量在内存中的分配
对于成员变量和局部变量:成员变量就是方法外部,类的内部定义的变量:局部变量就是方法或语句块内部定义的变量.局部变量必须初始化. 形式参数是局部变量,局部变量中基础数据类型的引用和值都存储在栈中,对象引 ...
- Java:成员变量、局部变量和静态变量
梳理一下: 根据定义变量位置的不同,可以将变量分成两大类:成员变量和局部变量. 成员变量(俗称全局变量):在类里定义的变量.又分为实例变量和类变量(也成为静态变量). 实例变量:不以static修饰, ...
- JAVA:成员变量和局部变量的区别
1.作用于不同: 局部变量的作用域仅限于定义它的方法 成员变量的作用域在整个类的内部都是可见的 2.初始值不同 JAVA会给成员变量一个初始值 JAVA不会给局部变量赋予初始值 3.在同一个方法中,不 ...
- [ 转载 ]Java:成员变量,局部变量,静态变量的区别
精简后方便自己理解. 成员变量 我们研究一个事物: 属性:外在特征:如身高,体重 行为:能做什么:如说话,打球. 在Java语言中,最基本的单位是类(class),类就是用来体现事物的. 属性:类中的 ...
- Java 中成员变量被局部变量所隐藏
Java 中局部变量与成员变量同名时,局部变量会隐藏成员变量.如果我们想访问成员变量,可以使用 this 关键字. class Test { private int value = 10; void ...
随机推荐
- 调用Oracle存储过程并获取out参数值
原文: http://tech.it168.com/oldarticle/2006-04-02/200604021512359.shtml http://www.cnblogs.com/m-cnblo ...
- 【C#】IDispose接口的应用
.net的GC机制有两个问题: 一.GC并不能释放所有资源,它更不能释放非托管资源. 二.GC也不是实时的,所有GC存在不确定性.所以需要使用析构函数,但是为了不重复GC,需要做一些处理. publi ...
- ASP.NET错误处理的方式(总结)
转载至: http://www.cnblogs.com/chinhr/archive/2007/06/26/795947.html ASP.NET错误处理的方式(整理&总结)英文文章研究:ht ...
- Linux 网络编程九(select应用--大并发处理)
//网络编程服务端 /* * 备注:因为客户端代码.辅助方法代码和epoll相同,所以select只展示服务器端代码 */ #include <stdio.h> #include < ...
- php基础03:数据类型
<?php // day01:数据类型 //01.字符串 $x = "hello world"; echo $x; echo "<br>"; ...
- String类及常用方法
在学习String类之前,先看一道笔试题:new String("abc")创建了几个对象? 答案: 两个对象, 一个对象是 位于字符串常量池中,一个对象是位于堆内存中. 原因:主 ...
- 在Linux用libcurl.a在链接的时候出错
其实出错是因为curl链接的时候需要别的库.我用如下方法解决 1.http://curl.haxx.se/download/curl-7.45.0.tar.gz官网下载源码 2../configure ...
- js实现网页防止被iframe框架嵌套及几种location.href的区别
首先我们了解一下几种location.href的区别简单的说:几种location.href的区别js实现网页被iframe框架功能,感兴趣的朋友可以了解下 首先我们了解一下:window.locat ...
- LINQ to Entities 查询语法
转自: http://www.cnblogs.com/asingna/archive/2013/01/28/2879595.html 实体框架(Entity Framework )是 ADO.NET ...
- 缓存算法之belady现象
前言 在使用FIFO算法作为缺页置换算法时,分配的缺页增多,但缺页率反而提高,这样的异常现象称为belady Anomaly. 虽然这种现象说明的场景是缺页置换,但在运用FIFO算法作为缓存算法时,同 ...