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 ...
随机推荐
- 【转】为什么我们都理解错了HTTP中GET与POST的区别
GET和POST是HTTP请求的两种基本方法,要说它们的区别,接触过WEB开发的人都能说出一二. 最直观的区别就是GET把参数包含在URL中,POST通过request body传递参数. 你可能自己 ...
- SQL Server 批量删除存储过程
原理很简单的'drop proc xxx'即可,下面有提供了两种方式来删除存储过程,其实本质是相同的,方法一是生成删除的sql后直接执行了,方法二会生成SQL,但需要检查后执行,个人推荐第二种做法. ...
- SEO:权重如何做到从0到1
SEO:权重如何做到从0到1 [写于2016年9月]我真的好久好久没到我的博客上去看过了,今天突然登上 seo.chinaz.com,搜索 dkplus.iteye.com,发现自己的博客在百度收录中 ...
- JavaWeb的国际化
国际化 1.国际化开发概述 1.1.软件的国际化 软件开发时,要使它能同时应对世界不同地区和国家的方法,并针对不同地区和国家的方法,提供相应的,符合来访者阅读习惯的页面或数据 国际化简称:i18n : ...
- PHP相关代码
1 <html> <head> <meta http-equiv="content-type" content="text/h ...
- JS中关于字符串的几个常用又容易忘记的方法
1>.字符串连接:concat(): 左边字符串. concat(连接的字符串1,字符串2,....); 获取指定位置的字符:charAt(): 返回指定位置的字符: 字符串.charAt(i ...
- DoraCMS 源码知识点备注
项目需要研究了下DoraCMS这款开源CMS,真心做的不错:).用的框架是常用的express 4 + mongoose,代码也很规范,值得学习. 源码中一些涉及到的小知识点备注下: https:// ...
- .NET中使用Redis (二)
很久以前写了一篇文章 .NET中使用Redis 介绍了如何安装Redis服务端,以及如何在.NET中调用Redis读取数据.本文简单介绍如何设计NoSQL数据库,以及如何使用Redis来存储对象. 和 ...
- hibernate多对一单向关联
关联是类(类的实例)之间的关系,表示有意义和值得关注的连接. 本系列将介绍Hibernate中主要的几种关联映射 Hibernate一对一主键单向关联Hibernate一对一主键双向关联Hiberna ...
- 2. Struts2 基础
1. Struts2简介 Struts2是一个WEB端MVC框架.作为比较早的MVC 框架之一,Struts2在使用中还是比较多的.虽然个人感受没有SpringMVC还那么的好用 Struts2 官网 ...