`
zhuyuyuseu
  • 浏览: 9278 次
  • 性别: Icon_minigender_1
  • 来自: 南通
社区版块
存档分类
最新评论

由浅入深Java线程之同步(一)

    博客分类:
  • Java
阅读更多

   在并发编程中经常会碰到多个执行线程共享资源的问题。例如多个线程同时读写文件,共用数据库连接,全局的计数器等。如果不处理好多线程之间的同步问题很容易引起状态不一致或者其他的错误。

   同步不仅可以阻止一个线程看到对象处于不一致的状态,它还可以保证进入同步方法或者块的每个线程,都看到由同一锁保护的之前所有的修改结果。处理同步的关键就是要正确的识别临界条件(critical section),即多线程访问/修改共享资源的代码块。

  关键字synchronized可以保证同一时刻,只有一个线程可以执行某个方法或者某个代码块。 此外Java语言规范保证读写一个变量是原子的,除非long或者double.虽然语言规范保证了线程在读取原子数据的时候,不会看到任意的数值,但是并不保证一个线程写入的值对于另一个线程是可见的,线程间的通信,同步是必要的。

  synchronized同步方法:

  我们可以把synchronized关键字放在方法前,保证同时只有一个线程执行该方法。需要注意的是如果一个类的静态方法和实例方法都有synchronized,那么同意时刻允许一个线程访问静态方法,另一个线程访问实例方法。例如:

  

private static synchronized void stopRequested(){
		stopRequest = true;
	}
   注意确保synchronized 方法仅仅是非常短的修改或者读取共享资源,否则会引起性能问题,因为synchronized本质上是互斥的。
  synchronized同步块:
   
synchronized (this) {
// Java code
}
  同步块可以让我们仅仅同步临界段,其余部分可以并行。 对于相互独立的共享资源,可以用不同的锁同步。例如同时售两个电影院的票:
   
public class Cinema {

	private long vacanciesCinema1;
	private long vacanciesCinema2;
	private final Object controlCinema1, controlCinema2;

	public Cinema() {
		controlCinema1 = new Object();
		controlCinema2 = new Object();
		vacanciesCinema1 = 20;
		vacanciesCinema2 = 20;
	}

	public boolean sellTickets1(int number) {
		synchronized (controlCinema1) {
			if (number < vacanciesCinema1) {
				vacanciesCinema1 -= number;
				return true;
			} else {
				return false;
			}
		}
	}

	public boolean sellTickets2(int number) {
		synchronized (controlCinema2) {
			if (number < vacanciesCinema2) {
				vacanciesCinema2 -= number;
				return true;
			} else {
				return false;
			}
		}
	}

}
   虽然读写primitive类型是原子的,但是如果线程之间不同步,还是会引起数据不一致问题,看下面这个例子:
 
public class TestStop {

	private static boolean stopRequest;
	
	public static void main(String[]args) throws InterruptedException{
		Thread t = new Thread( new Runnable(){
			public void run(){
				int i = 0;
				while(!stopRequest){
					i++;
				}
			}
		});
		t.start();
		TimeUnit.SECONDS.sleep(2);
		stopRequest = true;
	}
	
}
  这段代码有时候无法停止,因为子线程没看到主线程对stopRequest的改变。解决的办法是加上对共享变量的同步访问:
public class TestStop {

	private static boolean stopRequest;
	
	private static synchronized void stopRequested(){
		stopRequest = true;
	}
	
	private static synchronized boolean getStopRequest(){
		return stopRequest;
	}
	
	public static void main(String[]args) throws InterruptedException{
		Thread t = new Thread( new Runnable(){
			public void run(){
				int i = 0;
				while(!getStopRequest()){
					i++;
				}
			}
		});
		t.start();
		TimeUnit.SECONDS.sleep(2);
		stopRequested();
	}
	
}
    如果读写都没有同步,同步就没有效果。 针对此例,还可以用volatile,去掉同步。
    在后续章节中,我们将介绍更多关于synchronize及Lock的内容。
分享到:
评论

相关推荐

    由浅入深——Java 2自学教程 配书光盘.rar

    《由浅入深——Java 2自学教程》是一本旨在帮助初学者逐步掌握Java编程语言的书籍。配书光盘中的“由浅入深——Java 2自学教程 配书光盘.rar”压缩包文件,包含了书中所有工程素材和源码,这对于读者实践和理解Java...

    由浅入深学Java—基础、进阶与必做260题

    根据提供的文件信息,“由浅入深学Java—基础、进阶与必做260题”这份资料旨在为初学者提供全面深入的Java学习路径,不仅涵盖了基础知识的学习,还提供了大量的练习题帮助学习者巩固所学知识,并最终成长为一名优秀...

    由浅入深学Java — 基础、进阶与必做260题 高清 PDF

    《由浅入深学Java — 基础、进阶与必做260题》是一本详尽的Java学习指南,旨在为初学者至中级开发者提供全面的Java编程技能训练。本书通过清晰的结构和丰富的实践题目,帮助读者逐步掌握Java的核心概念和技术要点。 ...

    由浅入深学Java—基础、进阶与必做260题.pdf

    "由浅入深学Java—基础、进阶与必做260题.pdf"这本书旨在为学习者提供一个全面掌握Java技术的系统化路径,从基础知识到高级概念,再到实战练习,覆盖了Java学习的各个层面。 首先,Java的基础部分涵盖了以下知识点...

    java多线程编程源码范例和详细说明(由浅入深,深度解读在资料后半部分).docx

    在本文的后半部分,我们将进一步详细介绍多线程的高级概念和更复杂的应用场景,如线程同步、线程间通信、线程池等。 多线程编程的应用 多线程编程可以应用于各种场景,如数据处理、网络编程、图形处理等。通过多...

    由浅入深学Java-基础、进阶与必做

    Java是目前世界上使用最广泛的编程语言之一。它由Sun Microsystems公司于1995年推出,以其“一次编写,到处运行”的跨平台特性著称。Java的应用范围非常广泛,包括企业级应用、移动应用、游戏开发以及大数据处理等。...

    动力节点_Java基础视频教程219_线程-线程同步-没有同步的卖票

    动力节点的Java课程适合绝对零基础的观看,教程中讲解了Java开发环境搭建、Java的基础语法、...每一个知识点都讲解的非常细腻,由浅入深。适合非计算机专业,想转行做Java开发的朋友,或者想让Java基础更扎实的小伙伴。

    动力节点_Java基础视频教程220_线程-线程同步-使用同步锁的卖票

    动力节点的Java课程适合绝对零基础的观看,教程中讲解了Java开发环境搭建、Java的基础语法、...每一个知识点都讲解的非常细腻,由浅入深。适合非计算机专业,想转行做Java开发的朋友,或者想让Java基础更扎实的小伙伴。

    由浅入深学Java—基础、进阶与必做260题高清版

    - **定义**:Java是一种广泛使用的高级编程语言,由Sun Microsystems在1995年推出。 - **特点**:Java具有平台无关性、面向对象、安全性高、自动内存管理等特性。 #### 2. 开发环境搭建 - **JDK安装**:下载并安装...

    java并发编程实战范例(由浅入深代码范例和详细说明).docx

    本实战范例通过一个简单的计算整数平方的任务,展示了如何使用 Lock 接口以及其具体实现类 ReentrantLock 来实现线程同步,以及如何利用 ExecutorService 管理线程池来并发执行任务。以下是对这些知识点的详细解释:...

    完整版java基础入门教程由浅入深讲解 Java语言编程基础 第01章 java编程简介(共32页).ppt

    在第一章Java编程简介中,我们学习了Java语言的历史和特点,了解到Java是由Sun公司的James Gosling等人在1990年代初期开发的,最初命名为Oak。随着互联网的发展,Java逐渐转向Web应用程序,并在1995年正式发布。Java...

    动力节点_Java基础视频教程221_线程-如果避免同步

    动力节点的Java课程适合绝对零基础的观看,教程中讲解了Java开发环境搭建、Java的基础语法、...每一个知识点都讲解的非常细腻,由浅入深。适合非计算机专业,想转行做Java开发的朋友,或者想让Java基础更扎实的小伙伴。

    JAVA多线程精讲下

    多线程精讲下课程内容涵盖如下:l 线程的同步(线程安全问题)l 线程的死锁l 线程间通信l 线程组l 线程池l 多线程的第三种实现方案l 匿名内部类方式使用多线程l 定时器的使用l 多线程面试题

    java并发编程实战范例合集new(由浅入深代码范例和详细说明).docx

    3. **`CyclicBarrier` 和 `CountDownLatch`**:同步辅助类,前者用于一组线程等待彼此到达某个屏障点,后者则允许一个或多个线程等待其他线程完成操作。 4. **`Semaphore`**:信号量,用于控制同时访问特定资源的...

    java技术文档

    这部分内容对于开发多线程应用至关重要,因为Java是多线程编程的首选语言之一。 在进阶主题中,文档可能包含I/O流、网络编程、反射、注解和Java虚拟机(JVM)的工作原理。这些主题将帮助读者深入理解Java平台的内部...

    java并发编程实战范例(由浅入深代码范例和详细说明)(合集).docx

    【Java 并发编程实战范例】:在Java编程领域,并发编程是处理多线程和多任务同步的重要技术,它使得程序可以在多个处理器或核心上同时执行,从而提高系统的性能和效率。Java提供了丰富的并发工具和API,包括线程...

    java经典入门教程

    Java编程语言作为世界上最受欢迎的编程语言之一,是许多新手程序员的首选学习对象。"Java经典入门教程"提供了全面且深入的指导,旨在帮助零基础的学习者以及希望深化Java原理理解的开发者。本教程以精炼易懂的方式,...

Global site tag (gtag.js) - Google Analytics