Java基础知识笔记(五:多线程的同步问题)
编写多线程程序往往是为了提高资源的利用率,或者提高程序的运行效率,或者更好地监控程序的运行过程等。多线程同步处理的目的是为了让多个线程协调地并发工作。对多线程进行同步处理可以通过同步方法和同步语句块实现。Java虚拟机是通过对资源(如内存)加锁的方式实现这两种同步方式。这种机制带来的另一个问题就是死锁问题(即程序的所有线程都处于阻塞态或等待态)。良好的程序设计应当设法避开这种死锁问题。
一、多线程同步的基本原理
如果在多个并发线程之间共用资源,则可能就需要进行同步处理。Java虚拟机通过给每个对象加锁的方式实现多线程的同步处理。这里的对象包括类对象和实例对象两种。一个类的静态成员域和静态成员方法隶属于类对象。一个类的非静态成员域和非静态成员方法是不隶属于类对象的,而隶属于类的实例对象。
Java虚拟机为每个对象配备一把锁和一个等候集。对象内部锁住的是一些同步方法和同步语句块。一个方法要成为同步方法只要给该方法加上修饰词synchronized就可以。同步语句块的定义格式如下:
Synchronized(引用类型的表达式)
语句块
其中,关键字synchronized是同步语句块的引导词;位于“()”内的表达式必须是引用类型的表达式,指向某个类对象或实例对象,即指定与该同步语句块相关连的对象;语句块则由一对“{}”及这对大括号所括起来的一系列语句组成。
由于同步处理机制,Java虚拟机在运行同步方法或同步语句块时在时间和空间上需要一些额外开销。虽然利用多线程可以提高资源的利用率,但是如果过于频繁地用同步方法或同步语句块,则会降低多线程的并行度,并可能因为Java虚拟机的额外开销过大而最终降低程序的运行效率。
二、多线程的同步问题
(1)死锁问题
资源短缺会造成程序的所有线程都陷入等待态或阻塞态。死锁问题常常指的是造成这种情况的问题:资源实际上并不短缺,但由于程序设计不合理而造成程序的所有线程都处于等待态或阻塞态。典型的情况是每个线程都占有若干个资源的同时在等待若干个资源,而等待的资源都被其他线程所控制,所以每个线程都处于阻塞态。
(2)多线程同步的粒度问题
Java虚拟机通过Java语言的多线程特性提高了Java程序的运行效率。在多个线程之间常常因为共享内存等而需要同步处理。同步处理常常会降低线程的并行度,即让有些线程无法并行而只能串行。因此,很多资料认为多线程同步的粒度越小越好,即建议尽可能地减少在同步方法与同步语句块中的代码量,从而缩短多个线程串行运行的时间。实际上,这样会不会提高程序的运行效率是一个值得讨论的问题。这些资料忽略了Java虚拟机为线程的同步处理所需要的额外开销,即如果频繁地进入和退出同步方法或同步语句块,也会降低程序的运行效率。良好的多线程程序设计应当做好多线程同步的粒度与同步处理的次数之间的平衡关系,从而真正提高程序的运行效率。
Java基础知识笔记(五:多线程的同步问题)的更多相关文章
- java基础知识-笔记整理
1.查看已安装jdk文件路径 CMD输入java -verbose. 2.java学习提升路线 java学习视屏地址: http://www.icoolxue.com/album/show/38 ...
- Java基础知识强化之多线程笔记01:多线程基础知识(详见Android(java)笔记61~76)
1. 基础知识: Android(java)学习笔记61:多线程程序的引入 ~ Android(java)学习笔记76:多线程-定时器概述和使用
- java基础学习笔记五(抽象类)
java基础学习总结——抽象类 抽象类介绍
- Java基础知识强化之多线程笔记07:同步、异步、阻塞式、非阻塞式 的联系与区别
1. 同步: 所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回.但是一旦调用返回,就必须先得到返回值了. 换句话话说,调用者主动等待这个"调用"的结果. 对于 ...
- Java基础知识笔记(四:多线程基础及生命周期)
一.多线程基础 编写线程程序主要是构造线程类.构造线程类的方式主要有两种,一种是通过构造类java.lang.Thread的子类,另一种是通过构造方法实现接口java.lang.Runnable的类. ...
- Java基础学习笔记: 多线程,线程池,同步锁(Lock,synchronized )(Thread类,ExecutorService ,Future类)(卖火车票案例)
多线程介绍 学习多线程之前,我们先要了解几个关于多线程有关的概念.进程:进程指正在运行的程序.确切的来说,当一个程序进入内存运行,即变成一个进程,进程是处于运行过程中的程序,并且具有一定独立功能. 线 ...
- Java基础知识强化之多线程笔记06:Lock接口 (区别于Synchronized块)
1. 简介 我们讲到了如何使用关键字synchronized来实现同步访问.本文我们继续来探讨这个问题,从Java 5之后,在java.util.concurrent.locks包下提供了另外一种方式 ...
- Java基础知识强化之多线程笔记05:Java中继承thread类 与 实现Runnable接口的区别
1. Java中线程的创建有两种方式: (1)通过继承Thread类,重写Thread的run()方法,将线程运行的逻辑放在其中. (2)通过实现Runnable接口,实例化Thread类. 2. ...
- Java基础知识强化之多线程笔记05:Java程序运行原理 和 JVM的启动是多线程的吗
1. Java程序运行原理: Java 命令会启动Java 虚拟机,启动 JVM,等于启动了一个应用程序,也就是启动了一个进程.该进程会自动启动一个 “主线程” ,然后主线程去调用某个类的 m ...
随机推荐
- 似懂非懂的localStorage和sessionStorage
一.区别 相信很多人都见过这两个关于HTML5的新名词!HTML5种的web storage包含两种存储方式:localStorage和sessionStorage,这两种方式存储的数据不会自动发给服 ...
- SharePoint 2013管理中心里【管理服务器上的服务】不见了
打开管理中心,准备配置Managed Metadata Service,发现"管理服务器上的服务"不见了 那我自己拼url直接访问:http://xxxx/_admin/Serve ...
- Android中的flexboxlayout布局
提到FlexboxLayout大家估计有点模糊,它是谷歌最近开源的一个android排版库,它的前身Flexbox是2009年W3C提出了一种新的布局,可以简便.完整.响应式的实现页面布局,Flexb ...
- liunx 磁盘管理命令记录
Linux磁盘管理好坏管理直接关系到整个系统的性能问题. Linux磁盘管理常用三个命令为df.du和fdisk. df:列出文件系统的整体磁盘使用量 du:检查磁盘空间使用量 fdisk:用于磁盘分 ...
- transient关键字的用法
本篇博客转自 一直在路上 Java transient关键字使用小记 1. transient的作用及使用方法 我们都知道一个对象只要实现了Serilizable接口,这个对象就可以被序列化,Java ...
- Android(1)—Mono For Android 环境搭建及破解
0.前言 最近公司打算开发一款Android平台的简单报表查询软件,因本人之前一直是.NET开发的,和领导商定之后决定采用Mono For Android 进行开发,暂时采用破解版进行开发: 下文是记 ...
- Xamarin.Android下获取与解析JSON
一.新建项目 1.新建一个Android项目,并命名为为NetJsonList 2.右击引用,选择添加引用,引用System.Json.dll 二.同步请求 既然是跨平台,我们自然不能按照java下的 ...
- centos 7 安装mono 和 monodevelop
本次所有操作在root模式下 1.执行 rpm --import "http://keyserver.ubuntu.com/pks/lookup?op=get&search=0x3 ...
- Entity Framework 6 Recipes 2nd Edition(9-1)译->用Web Api更新单独分离的实体
第九章 在N层结构的应用程序中使用EF 不是所有的应用都能完全地写入到一个单个的过程中(就是驻留在一个单一的物理层中),实际上,在当今不断发展的网络世界,大量的应用程序的结构包含经典的表现层,应用程, ...
- linux安装mvn后提示权限不够
Maven - 环境配置 Maven 是一个基于 Java 的工具,所以要做的第一件事情就是安装 JDK. 系统要求 项目 要求 JDK Maven 3.3 要求 JDK 1.7 或以上Maven 3 ...