- 浏览: 1255511 次
- 性别:
- 来自: 杭州
文章分类
- 全部博客 (399)
- 心情故事 (12)
- java (115)
- linux (55)
- 关系型数据库 (35)
- struts,jsf,spring (11)
- jdbc,hibernate,ibatis (11)
- jsp,jstl,c:tag,标签库 (2)
- ejb,webservice (1)
- tomcat,jboss,jetty,weblogic,websphere (15)
- java网络编程 (6)
- java线程 (0)
- js,jquery,json,xml,dom,html.regex (25)
- 设计模式 (6)
- BUG记录 (2)
- ant (2)
- jsp,servlet (4)
- swing (6)
- lucene+nutch (6)
- log4j (2)
- windows doc (2)
- ruby (1)
- ruby on rails (3)
- 操作系统网络 (18)
- apache 错误 (1)
- tomcat (10)
- jboss (9)
- jetty (9)
- weblogic (9)
- websphere (10)
- apache (2)
- AIX的iostat命令查看系统磁盘的使用情况 (1)
- oracle 统计一个表格有多少列 (1)
- Exception in thread "main" java.security.KeyStoreException: Windows-MY not found (1)
- jsp (1)
- jstl (1)
- c:tag (1)
- 标签库 (1)
- struts (1)
- jsf (1)
- spring (2)
- oracle,sqlplus (2)
- sqlplus (2)
- show errors (1)
- proc (1)
- function (1)
- ORA-06544: PL/SQL: internal error (1)
- arguments: [55916] (1)
- [] (7)
- 终端身份实施文档 (1)
- 重装系统之后飞鸽传书只能看到自己 (1)
- vsftp "上传 553 Could not create file" (1)
- startWebLogic.sh启动失败,提示Error initializing Embedded LDAP Server (1)
- java agent 注册为 windows 服务 (1)
- centos (1)
- svn (1)
- apr (1)
- apr-util (1)
- activemq (2)
- oracle (5)
- mysql (3)
- nosql (3)
- NSIS (1)
- windows wmic (1)
- c 指针 (1)
- c c++ (0)
- jmeter (0)
- 性能测试 (0)
- linux,备份 (2)
- C++ ,Virtual (1)
- windows dos (1)
- android (2)
- 大数据,云计算 (1)
- JVM垃圾收集 (1)
- jdbc (2)
- invoke (1)
- hibernate (1)
- ibatis (1)
- 个人开源项目源码收藏 (1)
- 批处理 (1)
- Mongodb mapreduce (8)
- kettle (1)
- Mongodb capped (1)
- mongodb gridfs (1)
- Mongodb 入门基础知识 (1)
- mongodb (8)
- hadoop2.5.1 (1)
- hadoop (4)
- eclipse (1)
- hdfs fs (1)
- elipse hadoop plugin (1)
- PHP相关知识 (1)
- js (1)
- jquery (1)
- json (1)
- xml (1)
- dom (1)
- html.regex (1)
- 网络知识 (1)
- nginx (1)
- docker (1)
- 测试 (1)
- nodejs (1)
- iptables (1)
- linux gitlab (1)
最新评论
-
July01:
最近了解到一款StratoIO打印控件,功能如下:1、Html ...
web页面调用window.print()函数实现打印的功能 -
hxdtech:
非常感谢!
我在学习ibatis时的培训ppt -
zmwxiaoming:
what 能连数据库不错
SOLR的学习整理 -
springdata_springmvc:
java程序语言学习教程 地址http://www.zuida ...
java获取当前操作系统的信息 -
huanzei:
整理的不错,
oracle lpad函数
线程安全的本质体现在两个方面,
A变量安全:多线程同时运行一段代码
B线程同步:一个线程还没执行完,另一个线程又进来接着执行。
看个简单的例子。
public class ThreadSafe implements java.lang.Runnable { int num = 1; public void run() { for (int i = 0; i < 3; i++) { num = num + 1; try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("num is value +==="+Thread.currentThread().getName()+"---------" + num); } } }
public class TestMan {
public static void main(String[] args) {
Runnable safe=new ThreadSafe();
Thread thread1=new Thread(safe,"thread1");
Thread thread2=new Thread(safe,"thread2");
thread1.start();
thread2.start();
}
}
运行结果
num is value +===thread2---------3
num is value +===thread1---------4
num is value +===thread2---------5
num is value +===thread1---------6
num is value +===thread1---------7
num is value +===thread2---------7
很明显是错误的,应为两个线程共享同一个变量。这里就是变量的安全问题。
解决办法:
1抛弃单实例,多线程的方式,用多实例,多线程的方式,这样就和单线程是一个样了,不会出错,但是是最接近传统的编程模式
2不要用类的实例变量,经可能把变量封装到方法内部。
1类的解决办法的代码。
public class TestMan { public static void main(String[] args) { Runnable safe=new ThreadSafe(); Runnable safe2=new ThreadSafe(); Thread thread1=new Thread(safe,"thread1"); Thread thread2=new Thread(safe2,"thread2"); thread1.start(); thread2.start(); } }
运行结果
num is value +===thread1---------2
num is value +===thread2---------2
num is value +===thread1---------3
num is value +===thread2---------3
num is value +===thread1---------4
num is value +===thread2---------4
2类解决办法的代码
public class ThreadSafe implements java.lang.Runnable { public void run() { int num = 1; for (int i = 0; i < 3; i++) { num = num + 1; try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("num is value +==="+Thread.currentThread().getName()+"---------" + num); } } }
public class TestMan { public static void main(String[] args) { Runnable safe=new ThreadSafe(); Thread thread1=new Thread(safe,"thread1"); Thread thread2=new Thread(safe,"thread2"); thread1.start(); thread2.start(); } }
运行结果
num is value +===thread2---------2
num is value +===thread1---------2
num is value +===thread1---------3
num is value +===thread2---------3
num is value +===thread1---------4
num is value +===thread2---------4
这两种办法,比较推荐适用第二个办法,就是把变量经可能的封装到风发内部,这样他们就是线程的私有变量了。另外,从jdk1.2后,推出了threadlocal 对象,它作为线程的一个局部变量,可以为每个线程创建一个副本,用来保存每个线程的属性,各是各的,互不干扰。单每个threadlocal变量只能保存一个变量,假如有多个变量要保存,那么就要写多个threadlocal对象。
我们把代码改写一下。
public class ThreadSafe implements java.lang.Runnable { ThreadLocal<Integer> local=new ThreadLocal<Integer>(); public void run() { for (int i = 0; i < 3; i++) { if(local.get()==null){ local.set(new Integer(1)); } int num=local.get().intValue(); num=num+1; local.set(new Integer(num)); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("num is value +==="+Thread.currentThread().getName()+"---------" + local.get().intValue()); } } }
public class TestMan { public static void main(String[] args) { Runnable safe=new ThreadSafe(); Thread thread1=new Thread(safe,"thread1"); Thread thread2=new Thread(safe,"thread2"); thread1.start(); thread2.start(); } }
运行结果
num is value +===thread2---------2
num is value +===thread1---------2
num is value +===thread1---------3
num is value +===thread2---------3
num is value +===thread1---------4
num is value +===thread2---------4
结果是一样的,所以这里变量安全有3个办法可以解决。
然后在说说线程的同步的问题。我们看上面的运行结果。
num is value +===thread2---------2
num is value +===thread1---------2
num is value +===thread1---------3
num is value +===thread2---------3
num is value +===thread1---------4
num is value +===thread2---------4
就 可以看出他们不是线程同步的,是thread1和thread2在交替执行的。在有些情况下,要求一段代码在运行的过程中是一个不可分割的实体,就是原子的。就是说当已经有线程在执行这段代码的时候,其他的线程必须等待他执行完毕后才能竟来执行,这就是所谓的线程同步。
java通过同步锁来执行线程的同步和等待,也就是说,要不间断执行的代码需要放在synchronized关键字标识的代码块中。可以用来修饰代码块,也可以修饰方法。
public class ThreadSafe implements java.lang.Runnable{ public synchronized void run() { int num = 1; for (int i = 0; i < 3; i++) { num = num + 1; try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("num is value +==="+Thread.currentThread().getName()+"---------" + num); } } }
public class TestMan { public static void main(String[] args) { Runnable safe=new ThreadSafe(); Thread thread1=new Thread(safe,"thread1"); Thread thread2=new Thread(safe,"thread2"); thread1.start(); thread2.start(); } }
运行结果
um is value +===thread1---------2
num is value +===thread1---------3
num is value +===thread1---------4
num is value +===thread2---------2
num is value +===thread2---------3
num is value +===thread2---------4
可以看到thread1运行结束后thread2才开始运行的。代码还可以这么写
public class ThreadSafe implements java.lang.Runnable { public void run() { int num = 1; synchronized (this) { for (int i = 0; i < 3; i++) { num = num + 1; try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("num is value +===" + Thread.currentThread().getName() + "---------" + num); } } } }
在启用同步锁机制以后,需要避免
1无线等待,,线程B等待线程A执行完毕,然后线程A确进入了死循环。
2循环等待:两个线程相互调用,都要求要同步执行,这个时候就先会循环等待,我等你执行,你也在等我执行,这个时候就死锁了。
评论
synchronized (this) {
for (int i = 0; i < 3; i++) {
num = num + 1;
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("num is value +==="
+ Thread.currentThread().getName() + "---------" + num);
}
}
这里的this 到底指什么????
锁定该类对象的方法块,同时指让一个线程访问
synchronized (this) {
for (int i = 0; i < 3; i++) {
num = num + 1;
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("num is value +==="
+ Thread.currentThread().getName() + "---------" + num);
}
}
这里的this 到底指什么????
这个“多线程”就是多个Thread对象
但对所谓的 "多实例" 一直不是很了解
哪个用得多一些,
发表评论
-
centos6.5 hadoop伪分布式搭建
2017-01-10 10:41 25打算整理下machine learn ,再次安装 ... -
springboot
2016-12-29 11:13 2395微服务,现在是一个越来越热的东西,软件架构发展到 ... -
elk安装记录
2016-12-27 18:04 987在centos6.5上安装elk,记录下安装过程和 ... -
dubbo服务框架
2016-12-23 15:40 487上一篇文章介绍了zookeeper,作为服务 ... -
zookeeper服务注册中心配置
2016-12-22 11:40 1668用zookeeper有一段时间了,把配置做下简 ... -
OS X 安装java开发环境
2016-12-03 23:29 602... -
关于Restful API 的设计
2015-06-12 13:32 2282Restful API的流行,很大程度上被当前的移动 ... -
Jvisualvm远程连接tomcat配置:
2015-05-12 16:16 789JvisualVm 监控远程Tomcat,需要在To ... -
jdbc mybatis hibernate springJDBC的一些理解
2015-01-15 17:10 7071... -
Java 的ExecutorService
2015-01-15 11:45 1233早期在Java5以前,我们做多线程程序,一般都 ... -
spring的IOC和AOP
2015-01-14 16:47 2358关于Spring,大家都是耳熟 ... -
java 的线程安全
2014-12-30 14:43 981现代CPU基本都是多核,支持 ... -
JVM ClassLoader
2014-12-25 16:33 949JVM在加载类的时候,都是通过ClassLoad ... -
minor Gc ,Full Gc
2014-12-24 17:22 2108在发生Minor gc之前,虚拟机会先检查老年带最 ... -
Java的主要垃圾回收器
2014-12-24 16:33 1313对象 ... -
JVM的内存结构的一点理解
2014-12-24 11:30 785... -
利用生产者消费者模式实现串行的任务并行化
2014-12-22 17:48 1240试想,一个省有100个处理节点需要 ... -
利用生产者消费者模式实现串行的任务并行化
2014-12-22 17:48 0试想,一个省有100个处理节点需要 ... -
关于Linux的Ulimit参数
2014-12-22 12:13 1287JVM 64位平台与32位平台 ... -
一种表格数据比对的方法
2014-12-19 16:59 1060假设有连个库,一个是生产库,一个是备份库,在一个特 ...
相关推荐
理解并熟练运用这些线程安全集合是构建健壮、高性能的多线程Java应用程序的基础。它们能帮助开发者编写出更安全、更高效的代码,避免因并发问题导致的错误。同时,根据具体场景选择合适的集合类型,可以极大地提高...
Java的多线程是其编程语言中的一个重要特性,允许在单个程序中同时执行多个...在学习过程中,应重点掌握线程的创建、控制、同步和通信方法,以及如何处理线程安全问题,这样才能在实际项目中游刃有余地运用多线程技术。
总结来说,Java基础多线程练习题主要涵盖了线程的创建、同步与通信、线程安全以及并发工具的使用。通过这些题目,你可以更好地理解线程的工作原理,学会在实际项目中有效利用多线程提高程序性能,避免潜在的问题。在...
本文将结合上述 Bloch 关于线程安全等级的定义,对 Java 集合框架中的集合类进行线程安全性分析,并指出各个集合类在现实的编程环境中需要注意的并发编程的陷阱;同时对集合框架中通用算法对线程安全性的影响进行...
总的来说,理解和掌握Java线程的创建、状态管理、同步机制和线程安全是进行多线程编程的基础,这对于开发高效、稳定的并发程序至关重要。在实际编程中,应充分利用Java提供的工具和机制,避免潜在的并发问题,提升...
其实java的多线程并发问题最终都会反映在java的内存模型上,所谓线程安全无非是要控制多个线程对某个资源的有序访问或修改。总结java的内存模型,要解决两个主要的问题:可见性和有序性。我们都知道计算机有高速缓存...
4. **线程安全与死锁**:论文会讨论线程安全问题,如数据竞争和活锁,并分析如何预防和解决这些问题。同时,会介绍死锁的概念、死锁的四个必要条件,以及如何避免死锁的策略。 5. **多线程教学演示系统设计**:这...
Java程序中的线程是在操作系统级别的线程基础上进行抽象的。每个Java程序都有一个主线程,即由JVM启动并执行main方法的线程。线程代表了程序中的执行流,可以在不同的线程之间切换以共享CPU时间。线程的状态包括新建...
java多线程安全性基础介绍 线程安全 正确性 什么是线程安全性 原子性 竞态条件 i++ 读i ++ 值写回i 可见性 JMM 由于cpu和内存加载速度的差距,在两者之间增加了多级缓存导致,内存并不能直接对cpu可见。 ...
Java提供了多种机制来保证线程安全,比如使用synchronized关键字来同步方法或代码块,实现线程之间的同步。当一个线程试图进入一个已经被另一个线程持有的同步代码块时,它将进入阻塞状态,直到同步代码块的执行线程...
最后,线程安全的数据结构如ConcurrentHashMap、Atomic变量等,能够保证在多线程环境下正确地操作数据,提升并发性能。理解并熟练掌握这些概念和工具,是成为一名优秀的Java并发程序员必不可少的步骤。 总之,本...
此外,Java 5引入了BlockingQueue阻塞队列,它是一种线程安全的数据结构,线程可以等待队列中有数据可取或等待队列有空位可存,常用于生产者-消费者模型。 线程阻塞是指线程在运行过程中因为某些原因无法继续执行,...
1. **多线程基础**:多线程是Java编程中的一个重要概念,允许程序同时执行多个任务。在本示例中,通过创建多个`Thread`对象并调用它们的`run()`方法来实现并行处理数据库操作。 2. **数据库连接管理**:在多线程...
1. **线程安全**:由于多线程环境下可能存在数据竞争,所以在访问共享资源(如数据库连接)时,需要确保线程安全。可以使用`synchronized`关键字或者`Lock`来同步访问。 2. **事务管理**:在多线程环境中,可能需要...
在多线程环境下,共享资源(如Socket的输入/输出流)可能引发线程安全问题。因此,如果多个线程需要访问同一资源,需要使用`synchronized`关键字或者`java.util.concurrent`包下的工具来保证数据一致性,防止数据...
Java提供了一些线程安全的集合类,如ConcurrentHashMap、CopyOnWriteArrayList和CopyOnWriteArraySet,它们在多线程环境下提供了高并发的访问性能。 九、死锁检测与避免 死锁是多线程编程中的常见问题,两个或多个...
Java提供了`synchronized`关键字、`wait()`, `notify()` 和 `notifyAll()` 方法,以及`java.util.concurrent`包下的高级并发工具如`Semaphore`, `CyclicBarrier`, 和 `CountDownLatch`等,来确保线程安全和避免竞态...
在这个实例中,我们可能使用`synchronized`关键字来确保进度条更新时的线程安全,防止竞态条件的发生。 进度条的实现通常涉及一个主线程负责执行耗时任务,而另一个或多个线程负责更新用户界面(UI)。在Java中,...
13. **并发集合**:Java并发库提供了一些线程安全的集合,如`ConcurrentHashMap`, `CopyOnWriteArrayList`, `ConcurrentLinkedQueue`等,它们在多线程环境下表现更优。 在实际项目中,理解和熟练运用这些多线程知识...