在多线程访问的时候,同一时刻只能有一个线程能够用 synchronized 修饰的方法或者代码块,解决了资源共享。下面代码示意三个窗口购5张火车票:

 package com.jikexueyuan.thread;
/*
* 未使用synchronized,存在并发
*/
class RunnableDemo implements Runnable{
private int tickets = 5;
@Override
public void run() {
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (tickets>0) {
System.out.println("车票: "+tickets--);
}
} }
} public class ThreadTest { public static void main(String[] args) {
RunnableDemo r = new RunnableDemo();
Thread t1 = new Thread(r);
Thread t2 = new Thread(r);
Thread t3 = new Thread(r);
t1.start();
t2.start();
t3.start();
} }

其中一次的运行结果:

车票: 5
车票: 4
车票: 3
车票: 2
车票: 1
车票: 2

使用synchronized同步块后:

 package com.jikexueyuan.thread;
/*
* 使用synchronized块
*/
class RunnableDemo implements Runnable{
private int tickets = 5;
@Override
public void run() {
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (this) {
if (tickets>0) {
System.out.println("车票: "+tickets--);
}
}
}
}
} public class ThreadTest { public static void main(String[] args) {
RunnableDemo r = new RunnableDemo();
Thread t1 = new Thread(r);
Thread t2 = new Thread(r);
Thread t3 = new Thread(r);
t1.start();
t2.start();
t3.start();
} }

使用synchronized同步方法:

 package com.jikexueyuan.thread;
/*
* 使用synchronized同步方法
*/
class RunnableDemo implements Runnable{
private int tickets = 5;
@Override
public void run() {
for (int i = 0; i < 10; i++) {
show();
}
}
public synchronized void show() {
if (tickets>0) {
System.out.println("车票: "+tickets--);
}
}
} public class ThreadTest { public static void main(String[] args) {
RunnableDemo r = new RunnableDemo();
Thread t1 = new Thread(r);
Thread t2 = new Thread(r);
Thread t3 = new Thread(r);
t1.start();
t2.start();
t3.start();
} }

无论使用synchronized同步块还是同步方法,运行结果均为合理结果:

车票: 5
车票: 4
车票: 3
车票: 2
车票: 1

思考:volatile是另一种同步机制,是否可以呢?参考链接文章:Java理论与实践:正确使用Volatile变量 http://www.ibm.com/developerworks/cn/java/j-jtp06197.html

Java多线程同步机制之同步块(方法)——synchronized的更多相关文章

  1. Java多线程——线程之间的同步

    Java多线程——线程之间的同步 摘要:本文主要学习多线程之间是如何同步的,如何使用volatile关键字,如何使用synchronized修饰的同步代码块和同步方法解决线程安全问题. 部分内容来自以 ...

  2. Java多线程之线程的同步

    Java多线程之线程的同步 实际开发中我们也经常提到说线程安全问题,那么什么是线程安全问题呢? 线程不安全就是说在多线程编程中出现了错误情况,由于系统的线程调度具有一定的随机性,当使用多个线程来访问同 ...

  3. Java多线程运行机制的基本原理

    Java多线程运行机制的基本原理 进程和线程的区别 进程 进程是一个程序执行的实例,比如说我们打开10个IE浏览器窗口,那么就有10个进程开启.一个进程可以同时被运行若干次,进程是CPU进行资源分配和 ...

  4. 异常处理器详解 Java多线程异常处理机制 多线程中篇(四)

    在Thread中有异常处理器相关的方法 在ThreadGroup中也有相关的异常处理方法 示例 未检查异常 对于未检查异常,将会直接宕掉,主线程则继续运行,程序会继续运行 在主线程中能不能捕获呢? 我 ...

  5. Java 多线程基础(九)join() 方法

    Java 多线程基础(九)join 方法 一.join() 方法介绍 join() 定义 Thread 类中的,作用是:把指定的线程加入到当前线程,可以将两个交替执行的线程合并为顺序执行的线程.如:线 ...

  6. java多线程02-----------------synchronized底层实现及JVM对synchronized的优化

    java多线程02-----------------synchronized底层实现及JVM对synchronized的优化 提到java多线程,我们首先想到的就是synchronized关键字,它在 ...

  7. Java多线程之内存可见性和原子性:Synchronized和Volatile的比较

    Java多线程之内存可见性和原子性:Synchronized和Volatile的比较     [尊重原创,转载请注明出处]http://blog.csdn.net/guyuealian/article ...

  8. 浅谈Java多线程同步机制之同步块(方法)——synchronized

    在多线程访问的时候,同一时刻只能有一个线程能够用 synchronized 修饰的方法或者代码块,解决了资源共享.下面代码示意三个窗口购5张火车票: package com.jikexueyuan.t ...

  9. [java多线程] - 锁机制&同步代码块&信号量

    在美眉图片下载demo中,我们可以看到多个线程在公用一些变量,这个时候难免会发生冲突.冲突并不可怕,可怕的是当多线程的情况下,你没法控制冲突.按照我的理解在java中实现同步的方式分为三种,分别是:同 ...

随机推荐

  1. rails应用中各数据平台的对接

    1.mongo #Gemfile添加如下两个gem包gem 'mongoid', '~> 5.1.0' gem 'mongo', '~> 2.4’ @client = Mongo::Cli ...

  2. C指针(4)——数据结构中指针的应用(非常重要)

    5-1动态内存分配,分配的是堆内存的空间 分配内存函数 (都集中在库函数 stdlib.h  中) void *malloc (unsigned int num_bytes); //指定分配内存空间大 ...

  3. Redis 常用数据结构命令

    1. 字符串(string) 增加元素 set key value [EX seconds] [PX milliseconds] [NX|XX] EX seconds:为键设置秒级过期时间 PX mi ...

  4. 构建工具——maven的补充

    1.安装jar到本地仓库 有时候有部分jar由于在maven的中央仓库,只能引用本地的,可以将jar安装到本地仓库进行操作(请先确保mvn命令可以正常运行) mvn install:install-f ...

  5. WPF的退出

    很多时候,会自己写退出程序的代码. 比如,先显示登录框(LogIn),成功后隐藏它,并显示一个主窗体(MainWin),或者外部还调用了其他App,当你关闭MainWin不一定会直接退出整个程序的. ...

  6. SQL 注入、XSS 攻击、CSRF 攻击

    SQL 注入.XSS 攻击.CSRF 攻击 SQL 注入 什么是 SQL 注入 SQL 注入,顾名思义就是通过注入 SQL 命令来进行攻击,更确切地说攻击者把 SQL 命令插入到 web 表单或请求参 ...

  7. 开胃小菜——impress.js代码详解

    README 友情提醒,下面有大量代码,由于网页上代码显示都是同一个颜色,所以推荐大家复制到自己的代码编辑器中看. 今天闲来无事,研究了一番impress.js的源码.由于之前研究过jQuery,看i ...

  8. uvaoj 101 - The Blocks Problem(vector应用+技巧)

    https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=835&page= ...

  9. jmeter关联三种常用方法

    在LR中有自动关联跟手动关联,但在我看来手动关联更准确,在jmeter中,就只有手动关联 为什么要进行关联:对系统进行操作时,本次操作或下一次操作对服务器提交的请求,这参数里边有部分参数需要服务器返回 ...

  10. Linux命令应用大词典-第26章 模块和内核管理

    26.1 lsmod:显示内核中模块的状态 26.2 get_module:查看内核模块详细信息 26.3 modinfo:显示内核模块信息