- 浏览: 256639 次
- 性别:
- 来自: 苏州
文章分类
最新评论
-
a542550187:
很受用,最近正好学习软件工程方面的知识
如何建立领域模型(转) -
liiyee:
谢谢!中文版有些地方的翻译实在是挺对付的。
hibernate in action 2 英文版 -
HFLdragon:
下来学习一下
ajax upload file -
wendellup_account1:
thanks....
Spring 3 mvc Validation的错误 -
zhangjq5:
中文名乱码……
ajax upload file
线程同步指多个线程同时访问某资源时,采用一系列的机制以保证同时最多只能一个线程访问该资源。
为什么需要线程同步呢?
我们举一个最简单的例子来说明为什么需要线程同步。
比如有一本书(有且只有一本),交给多个售货员同时去卖;
如果其中任何一个售货员把这本书给卖了,其他售货员就不能再卖这本书了。
现实生活中,如果要保证该书不会被多个售货员同时卖掉,必须要有一种机制来保证:
比如,售货员应该拿到该书之后才能开始卖书,暂时拿不到的话就只能等该书被退回柜台。
这里,每一个售货员售书可以看作一个线程。欲售的书便是各线程需要共享的资源。
开始售书之前,需要取得该书(资源),取不到情况下等待:资源取得
开始售书之后,则需要取得对该书的独享控制(不让他人拿到该书):资源加锁
售完书时,需要通知柜台该书已售出;或者未售出时,把书退回柜台(通知他人可以拿到该书):资源解锁
synchronized控制线程同步的概念跟此完全一样。
Java里可以使用synchronized来同步代码块或者方法。
同步代码块例:
- synchronized(欲同步的对象obj) {
- 需要同步的代码块
- }
synchronized(欲同步的对象obj) { 需要同步的代码块 }
可以同步代码块。
synchronized (obj) 表示若多个线程同时访问时,只让其中一个线程最先取得obj对象并对其加锁,其它线程则阻塞直到取得obj对象的线程执行完代码块,此时被加锁的obj对象得到释放(解锁),其它线程得到通知取得该book对象继续执行。
很多情况下,可以使用synchronized (this){...}来同步代码块。但需要注意的是,使用this作为同步对象的话,如果同一个类中存在多个synchronized (this){...}代码块,其中任何一个synchronized(this)代码块处于被执行状态,则其它线程对其他synchronized(this)代码块的访问也会受到阻塞。
为了说明这个问题,我们举例说明:
HelloSynchronized.java
- public class HelloSynchronized {
- public static void main(String[] args) {
- //
- HelloSynchronized helloSynchronized = new HelloSynchronized();
- //创建2个线程t1, t2,分别调用HelloSynchronized helloSynchronized的2个方法method1,与method2
- Thread t1 = new Thread(new HelloSynchronizedRunnalbe(helloSynchronized, "method1"), "t1");
- Thread t2 = new Thread(new HelloSynchronizedRunnalbe(helloSynchronized, "method2"), "t2");
- t1.start();
- t2.start();
- }
- //synchronized public void method1() { //同步方法
- public void method1() {
- synchronized (this) { //同步块
- System.out.println(Thread.currentThread().getName()
- + " enter method1");
- try {
- Thread.sleep(3000);
- } catch (InterruptedException e) {
- // do nothing
- }
- System.out.println(Thread.currentThread().getName()
- + " exit method1");
- }
- }
- //synchronized public void method2() { //同步方法
- public void method2() {
- synchronized (this) { //同步块
- System.out.println(Thread.currentThread().getName()
- + " enter method2");
- try {
- Thread.sleep(3000);
- } catch (InterruptedException e) {
- // do nothing
- }
- System.out.println(Thread.currentThread().getName()
- + " exit method2");
- }
- }
- }
- class HelloSynchronizedRunnalbe implements Runnable {
- private HelloSynchronized helloSynchronized;
- private String methodName;
- public HelloSynchronizedRunnalbe(HelloSynchronized helloSynchronized, String methodName) {
- this.helloSynchronized = helloSynchronized;
- this.methodName = methodName;
- }
- public void run() {
- if (methodName.equals("method1")) {
- helloSynchronized.method1();
- } else if (methodName.equals("method2")) {
- helloSynchronized.method2();
- }
- }
- }
public class HelloSynchronized { public static void main(String[] args) { // HelloSynchronized helloSynchronized = new HelloSynchronized(); //创建2个线程t1, t2,分别调用HelloSynchronized helloSynchronized的2个方法method1,与method2 Thread t1 = new Thread(new HelloSynchronizedRunnalbe(helloSynchronized, "method1"), "t1"); Thread t2 = new Thread(new HelloSynchronizedRunnalbe(helloSynchronized, "method2"), "t2"); t1.start(); t2.start(); } //synchronized public void method1() { //同步方法 public void method1() { synchronized (this) { //同步块 System.out.println(Thread.currentThread().getName() + " enter method1"); try { Thread.sleep(3000); } catch (InterruptedException e) { // do nothing } System.out.println(Thread.currentThread().getName() + " exit method1"); } } //synchronized public void method2() { //同步方法 public void method2() { synchronized (this) { //同步块 System.out.println(Thread.currentThread().getName() + " enter method2"); try { Thread.sleep(3000); } catch (InterruptedException e) { // do nothing } System.out.println(Thread.currentThread().getName() + " exit method2"); } } } class HelloSynchronizedRunnalbe implements Runnable { private HelloSynchronized helloSynchronized; private String methodName; public HelloSynchronizedRunnalbe(HelloSynchronized helloSynchronized, String methodName) { this.helloSynchronized = helloSynchronized; this.methodName = methodName; } public void run() { if (methodName.equals("method1")) { helloSynchronized.method1(); } else if (methodName.equals("method2")) { helloSynchronized.method2(); } } }
运行结果为:
t1 exit method1
t2 enter method2
t2 exit method2
等到线程t1结束后,t2才开始运行(t2受到阻塞)
再把synchronized (this)去掉,运行结果为:
t2 enter method2
t1 exit method1
t2 exit method2
线程t1,t2同时运行
同步方法例:
- synchronized private void sellBook(Book book) {
- ...
- }
synchronized private void sellBook(Book book) { ... }
这种方法其实相当于
- private void sellBook(Book book) {
- synchronized(this) {
- ...
- }
- }
private void sellBook(Book book) { synchronized(this) { ... } }
由于默认采用this作为同步对象,所以当一个类中有多个synchronized方法时,同样会存在以上问题:即如果有一个线程访问其中某个synchronized方法时,直到该方法执行完毕,其它线程对其它synchronized方法的访问也将受到阻塞。
大家可以把上面的例子稍加改造,去掉代码中的synchronized (this),改为synchronized public void method1(),synchronized public void method2()同步形式,运行后会得到同样结果。
多同步代码块synchronized(this){...}的多线程阻塞问题(包括synchronized同步方法),在并发处理的系统中(比如WEB服务器)会严重影响性能,建议慎重使用。可以使用synchronized(obj){...}缩小同步资源对象的范围来解决这个问题。
发表评论
-
IDEA EvalRest
2022-03-10 17:19 0Download and install plugi ... -
使用maven-jar-plugin将部分源代码打成Jar,并引入到项目使用。
2020-05-08 16:40 708需求:因为项目(单体系统)里尽可能保证项目里一部分源码,所以 ... -
CAS与spring3集成
2013-04-12 09:47 1125CAS 下载地址 https://wiki.jasig.o ... -
如何在Spring 3 MVC整合Apache CXF开发Webservice服务
2012-09-11 16:06 3558如何在Spring 3 MVC框架下结合CXF开发Webser ... -
如何在Spring 3 下结合结束大CXF开发WebService接口
2012-09-10 21:15 0如何从Spring 3 MVC架构下与Apache CXF开发 ... -
Java文件简单读写(转)
2011-10-22 15:45 880最近用Java处理文件的时候,同样遇到了中文问题,觉得还是 ... -
Java基本类型与包装类判断
2011-10-22 13:42 14496public class Test{ public sta ... -
Java深度历险合集
2011-08-26 16:43 857Java深度历险.pdf -
Apache Click 一个Java企业版的Web应用程序框架
2011-08-24 13:52 876Apache Click 是一个先进的Java企业版的Web应 ... -
Java的异常处理总结
2011-08-10 22:42 1307一、 异常的概念和Java异常体系结构 异常是程 ... -
Java反射与动态代理
2011-07-01 16:24 0在介绍Java注解的时候,多次提到了Java的反射 ... -
Red5+OpenOffice+OpenMeetings架设视频会议网络(转)
2011-05-25 14:17 1753因工作需要,这两天弄 ... -
DOM4J学习笔记(转)
2011-02-16 15:47 592Loading XML Data 以下代码从File中或 ... -
Hibernate级联删除的问题
2011-01-25 14:50 1023在one-to-many 关联时,one方一般都需要有控制级联 ... -
fmt:formatDate 的输出格式
2011-01-22 23:28 955fmt:formatDate 的输出格式 <fmt ... -
Tomcate启动内存设置
2010-10-19 16:41 738其初始空间(即-Xms)是物理内存的1/64,最大空 ... -
基于json-lib.jar包Json实例程序(转)
2010-10-18 20:22 3470基于json-lib.jar包Json实例程序 ... -
Aache下的AB性能测试工具(转)
2010-10-18 16:57 897以前安装好APACHE总是 ... -
四步将Myeclipse的web project部署到eclipse中的tomcat
2010-10-15 16:29 2103现在很多Web的项目都是在MyEclipse中开发测试完成的 ... -
实现集合中对象的排序功能
2010-09-29 18:10 717利用Set可以去掉重复的对象,利用list可以对象自然排序,如 ...
相关推荐
例如,可以使用start()方法启动线程,使用join()让当前线程等待另一个线程完成,使用synchronized关键字进行线程同步,防止数据竞争。此外,还可以使用wait()、notify()和notifyAll()方法进行线程间的协作。 Java的...
线程在执行过程中需要互相配合,确保某个任务的正确完成,比如等待...正确理解和使用线程同步技术是编写高效、安全的多线程程序的关键。在实际开发中,应根据具体场景选择合适的同步策略,以实现最佳性能和可维护性。
4. **线程同步** - **锁(Synchronized)**:使用`synchronized`关键字实现互斥访问,保证同一时刻只有一个线程访问特定代码块。 - **死锁(Deadlock)**:多个线程相互等待对方释放资源导致的僵局,避免死锁需...
Java提供多种同步机制,包括使用 `synchronized` 关键字、显式锁(`Lock`)、原子变量等。 #### 二、核心类库 **1. 字符串处理** - **String**:不可变的字符序列,适用于频繁的字符串拼接操作较少的情况。 - **...
5. **并发工具类**:如CountDownLatch、CyclicBarrier、Semaphore、Future等,它们在多线程协作和同步中的作用。 6. **原子操作类**:AtomicInteger、AtomicLong等,它们提供了一种无锁的并发编程方式。 通过阅读...
7. **同步与并发**:在多线程环境下,Java编程规范提供了关于同步和并发的指导,如使用synchronized关键字、volatile变量、并发容器等,以保证数据一致性。 8. **代码效率**:书中讨论了如何通过优化循环、减少对象...
使用synchronized关键字同步的代码块也能保证写操作的可见性。HappenBefore法则定义了一系列规则,用来保证代码执行的有序性和可见性,比如程序次序法则、监视器法则、volatile变量法则等。 可排序性 Java并发编程...
线程同步机制(如synchronized关键字、volatile、Lock接口)、并发工具类(如Semaphore、CyclicBarrier、CountDownLatch)以及并发集合(如ConcurrentHashMap)的应用,都是面试中可能涉及的内容。 五、JVM内存模型...
两者的线程同步机制在转换时需要注意。 11. **注解(Annotations)**:Java中的注解在C#中对应为特性(Attributes)。在转换过程中,需要确保这些元数据能够正确地迁移。 12. **编译器特性**:C#的Roslyn编译器...
在这种情况下,通常需要使用`synchronized`或者`AtomicInteger`等并发工具类来确保原子性。 总结,`volatile`关键字在多线程编程中起到关键作用,它提供了轻量级的同步机制,但要注意其局限性,对于需要原子性保证...
9. **线程同步**: - `synchronized`关键字用于控制多线程对共享资源的访问,防止数据不一致。 10. **异常处理**: - 使用`try-catch-finally`结构捕获并处理异常,确保资源在任何情况下都能正确释放。 11. **...
3. **同步与互斥**:为了防止多个线程同时访问共享资源,Java提供了`synchronized`关键字、`Lock`接口(如`ReentrantLock`)和`java.util.concurrent`包中的并发工具类,以实现线程间的同步和互斥。 4. **死锁、...
线程同步:synchronized关键字、锁(Lock接口)、原子变量等。 线程池及并发包:Executors、ForkJoinPool、CountDownLatch、CyclicBarrier等。 并发优化:CAS、无锁编程、AQS原理等。 内容不限于这些,适合中、大厂...
Java提供了多种并发控制机制,如synchronized关键字、volatile变量、Lock接口(ReentrantLock、ReadWriteLock等)、Semaphore信号量、CountDownLatch倒计时锁和CyclicBarrier同步屏障等,这些工具用于管理线程间的...
- 使用synchronized关键字实现线程安全,了解Thread和Runnable接口的区别。 7. **反射**: - 反射机制允许程序在运行时动态地获取类的信息并调用其方法,提供了强大的动态性。 8. **泛型**: - 泛型引入后,...
- 掌握线程的创建、同步和通信方法,如synchronized关键字、wait/notify机制。 - 学习线程池的使用和配置,如ExecutorService。 5. **JAVA反射机制**: - 学习如何在运行时动态获取类信息,创建对象,调用方法。...
书中有详尽的线程同步和通信技术,如synchronized关键字、wait()、notify()方法,以及Lock接口和Condition对象的使用。 最后,书中还会涉及Java的高级特性,如反射、注解、动态代理等,这些特性在实际开发中有着...
catch (InterruptedException e)//当线程在活动之前或活动期间处于正在等待、休眠或占用状态且该线程被中断时,抛出该异常 { e. printStackTrace(); } } ava=false; notifyAll(); return contents; } public ...
Java并发编程中的ReentrantLock是Java并发包(java....它使得开发者能够更好地控制并发环境中的线程同步,提高程序的效率和安全性。在实际开发中,根据具体需求选择合适的锁类型,可以有效避免并发问题,提升系统性能。
3. **同步机制**:为了保证文件的完整性,线程之间需要进行同步。Java提供了多种同步机制,如`synchronized`关键字、`Lock`接口(如`ReentrantLock`)以及`java.util.concurrent`包中的工具类,用于确保线程安全地...