一.理解同步

要想解决资源共享的同步操作问题,可以使用两种方法:

  1. 使用同步代码块

之前学习过程中,代码块分为四种:

l         普通代码块:是直接定义在方法之中的;

l         构造块:是直接定义在类中的,优先于构造方法执行,会重复调用;

l         静态块:是使用static关键字声明的,优先于构造块执行,并且只执行一次;

l         同步代码块:是使用synchronized关键字声明的代码块,称为同步代码块

同步的时候必须指明同步的对象,一般情况下会将当前对象作为同步的对象,使用this关键字表示。 注意,同步会使程序运行变慢!

代码如下:

package cn.test.java.mutilthread;

class SyncThread2 implements Runnable{

private int ticket = 10;

public void run(){

for(int i = 0;i>10;i++){

synchronized (this) {

if(this.ticket>0){

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

System.out.println(Thread.currentThread().getName()+"剩下票数:"+ticket--);

}

}

}

}

}

public class SyncThreadDemo2 {

public static void main(String[] args) {

SyncThread2 t = new SyncThread2();

Thread t1 = new Thread(t);

Thread t2 = new Thread(t);

Thread t3 = new Thread(t);

t1.start();

t2.start();

t3.start();

}

}

  1. 使用同步方法

package cn.test.java.mutilthread;

class SyncThread3 implements Runnable{

private int ticket = 10;

public void run(){

for(int i = 0;i>10;i++){

this.sale();// 调用同步方法

}

}

public synchronized void sale(){ //声明同步方法

if(this.ticket>0){

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

System.out.println(Thread.currentThread().getName()+"剩下票数:"+ticket--);

}

}

}

public class SyncThreadDemo3 {

public static void main(String[] args) {

SyncThread3 t = new SyncThread3();

Thread t1 = new Thread(t);

Thread t2 = new Thread(t);

Thread t3 = new Thread(t);

t1.start();

t2.start();

t3.start();

}

}

二.理解死锁

死锁的出现是因为多个线程占用资源之后,没有进行释放,导致其他线程一直处于等待状态,在我们在代码中,出现死锁的原因有很多,极大多数是因为我们代码中编成的同步代码过多导致死锁的,

注意:使用synchronized同步代码中嵌入synchronized代码,非常容易导致死锁的出现。

代码如下:

class Zhangsan{     // 定义张三类

public void say(){

System.out.println("张三对李四说:“你给我画,我就把书给你。”") ;

}

public void get(){

System.out.println("张三得到画了。") ;

}

};

class Lisi{      // 定义李四类

public void say(){

System.out.println("李四对张三说:“你给我书,我就把画给你”") ;

}

public void get(){

System.out.println("李四得到书了。") ;

}

};

public class ThreadDeadLock implements Runnable{

private static Zhangsan zs = new Zhangsan() ;            // 实例化static型对象

private static Lisi ls = new Lisi() ;        // 实例化static型对象

private boolean flag = false ;  // 声明标志位,判断那个先说话

public void run(){   // 覆写run()方法

if(flag){

synchronized(zs){  // 同步张三

zs.say() ;

try{

Thread.sleep(500) ;

}catch(InterruptedException e){

e.printStackTrace() ;

}

synchronized(ls){

zs.get() ;

}

}

}else{

synchronized(ls){

ls.say() ;

try{

Thread.sleep(500) ;

}catch(InterruptedException e){

e.printStackTrace() ;

}

synchronized(zs){

ls.get() ;

}

}

}

}

public static void main(String args[]){

ThreadDeadLock t1 = new ThreadDeadLock() ;         // 控制张三

ThreadDeadLock t2 = new ThreadDeadLock() ;         // 控制李四

t1.flag = true ;

t2.flag = false ;

Thread thA = new Thread(t1) ;

Thread thB = new Thread(t2) ;

thA.start() ;

thB.start() ;

}

};

三.总结

1.多个线程在访问同一资源的时候需要进行同步操作。

2.同步使用synchronized关键字完成,分为同步代码块及同步方法。

3.过多的同步有可能造成死锁的产生,死锁是在程序运行时的一种状态,了解就行了。

4.想停止线程,在代码中设置标志位flag,利用标志位来控制线程在生命周期。

理解java中【同步】和【死锁】的更多相关文章

  1. 理解Java中的弱引用(Weak Reference)

    本篇文章尝试从What.Why.How这三个角度来探索Java中的弱引用,理解Java中弱引用的定义.基本使用场景和使用方法.由于个人水平有限,叙述中难免存在不准确或是不清晰的地方,希望大家可以指出, ...

  2. 深刻理解Java中final的作用(一):从final的作用剖析String被设计成不可变类的深层原因

    声明:本博客为原创博客,未经同意,不得转载!小伙伴们假设是在别的地方看到的话,建议还是来csdn上看吧(原文链接为http://blog.csdn.net/bettarwang/article/det ...

  3. [译]线程生命周期-理解Java中的线程状态

    线程生命周期-理解Java中的线程状态 在多线程编程环境下,理解线程生命周期和线程状态非常重要. 在上一篇教程中,我们已经学习了如何创建java线程:实现Runnable接口或者成为Thread的子类 ...

  4. 深入理解Java中的不可变对象

    深入理解Java中的不可变对象 不可变对象想必大部分朋友都不陌生,大家在平时写代码的过程中100%会使用到不可变对象,比如最常见的String对象.包装器对象等,那么到底为何Java语言要这么设计,真 ...

  5. 深入理解Java中的IO

    深入理解Java中的IO 引言:     对程序语言的设计者来说,创建一个好的输入/输出(I/O)系统是一项艰难的任务 < Thinking in Java >   本文的目录视图如下: ...

  6. 理解Java中的ThreadLocal

    提到ThreadLocal,有些Android或者Java程序员可能有所陌生,可能会提出种种问题,它是做什么的,是不是和线程有关,怎么使用呢?等等问题,本文将总结一下我对ThreadLocal的理解和 ...

  7. 深入理解Java中配置环境变量

    深入理解Java中配置环境变量 配置的目的: 本来只在安装JDK的bin目下能运行java.exe,javac.exe,jar.exe,javadoc.exe等Java开发工具包命令,我们现在想让在所 ...

  8. 十分钟理解Java中的动态代理

    十分钟理解 Java 中的动态代理   一.概述 1. 什么是代理 我们大家都知道微商代理,简单地说就是代替厂家卖商品,厂家“委托”代理为其销售商品.关于微商代理,首先我们从他们那里买东西时通常不知道 ...

  9. 理解Java中【包】的概念

    Java中用package关键字定义一个包,下面通过几个实验,理解Java中的包的概念和作用. 实验1:先看一个无包的情形 在G盘下新建一个Test.java,如图1: 写下面这些代码 <spa ...

  10. JDK学习---深入理解java中的HashMap、HashSet底层实现

    本文参考资料: 1.<大话数据结构> 2.http://www.cnblogs.com/dassmeta/p/5338955.html 3.http://www.cnblogs.com/d ...

随机推荐

  1. IOS 怎么修改Navigation Bar上的返回按钮文本颜色,箭头颜色以及导航栏按钮的颜色

    self.navigationController.navigationBar.barTintColor = [UIColor blackColor]; self.navigationControll ...

  2. Android应用程序资源的编译和打包过程分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/8744683 我们知道,在一个APK文件中,除了 ...

  3. 为项目编写Readme.MD文件

    了解一个项目,恐怕首先都是通过其Readme文件了解信息.如果你以为Readme文件都是随便写写的那你就错了.github,oschina git gitcafe的代码托管平台上的项目的Readme. ...

  4. SQLLoader6(一个或多个数据文件按条件导入不同的表)

    测试一1.创建表: SQL), col2 )); 表已创建. SQL), col2 )); 表已创建. SQL> COMMIT; 提交完成. 2.数据文件:test.txt A A A B B ...

  5. 推荐几个常用的jquery ui 框架

    jQuery ui框架很多,除了官方提供的jquery UI(如果你还不知道什么是jQuery UI,请看下载了jquery ui后如何使用),还有很多第三方提供的ui框架,因官方提供的jquery ...

  6. asp.net mvc输出自定义404等错误页面,非302跳转

      朋友问到一个问题,如何输出自定义错误页面,不使用302跳转.当前页面地址不能改变. 还要执行一些代码等,生成一些错误信息,方便用户提交反馈. 500错误,mvc框架已经有现成解决方法: filte ...

  7. mono for android工具下载

    http://www.wuleba.com/25510.html Windows平台:http://xamarin.com/installer_assets/v3/Windows/Universal/ ...

  8. sketchup 导出 fbx文件 单位 错误

    最近在使用sketchup导出fbx文件到unity中使用时,发生了尺度单位上的错误.按照网上给出的标准教程,选定模型的单位为十进制-米.导出时选项选择'米',但是得到的fbx文件在unity中出现了 ...

  9. SQLSERVER和sybase的差异

    sybase sqlserver *= left join =* right join

  10. C# ?? 运算符,不能忘记的知识点

    最近项目中有一个bug被测试(是黑盒测试)发现了,跟了老半天代码,才找到这个问题的所在,原来是一个计算表达式中用到了??运算符,才导致了这个错误,下面让我简单讲述一下. C# ?? 运算符 msdn上 ...