java同步synchronized
volatile仅仅用来保证该变量对所有线程的可见性,但不保证原子性。
看下面的这段代码:
/**
*
* @author InJavaWeTrust
*
*/
public class CountVolatile implements Runnable {
public static CountVolatile instance = new CountVolatile();
public static volatile int i = 0;
public static void increate() {
i++;
}
public void run() {
for (int c = 0; c < 10000000; c++) {
increate();
}
}
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(instance);
Thread t2 = new Thread(instance);
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println(i);
}
}
这段代码演示了一个计数器,两个线程同时对i进行累加,个执行10000000次。我们希望的执行结果是最终i的值可以达到20000000,但事实并非总是如此。很多时候,i的值会小于期望的数值20000000。这是因为两个线程同时对i进行写入时,其中一个线程的结果会覆盖另外一个线程的结果。
要从根本上解决这个问题,我们就必须保证多个线程在对i进行操作时完全同步。
关键字synchronized的作用是实现线程间的同步。当它锁定一个方法或者一个代码块的时候,同一时刻最多只有一个线程执行这段代码。当两个并发线程访问同一个对象object中的这个加锁同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。
关键字synchronized的几种用法。
- 指定加锁对象:对给定对象加锁,进入同步代码钱要获得给定对象的锁。
- 直接作用于实例方法:相当于对当前实例加锁,进入同步代码前要获得当前实例的锁。
- 直接作用于静态方法:相当于对当前类加锁,进入同步代码前要获得当前类的锁。
一、指定加锁对象:
/**
*
* @author InJavaWeTrust
*
*/
public class CountSynchronized implements Runnable {
public static CountSynchronized instance = new CountSynchronized();
public static int i = 0;
public void run() {
for (int c = 0; c < 10000000; c++) {
synchronized(instance) { //对给定对象加锁
i++;
}
}
} public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(instance);
Thread t2 = new Thread(instance);
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println(i);
}
}
二、直接作用于实例方法:
/**
*
* @author InJavaWeTrust
*
*/
public class CountSynchronized2 implements Runnable {
public static CountSynchronized2 instance = new CountSynchronized2();
public static int i = 0;
public synchronized void increate() { //对当前实例方法加锁
i++;
}
public void run() {
for (int c = 0; c < 10000000; c++) {
increate();
}
} public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(instance);
Thread t2 = new Thread(instance);
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println(i);
}
}
三、直接作用于静态方法:
/**
*
* @author InJavaWeTrust
*
*/
public class CountStaticMethod implements Runnable {
static int i = 0;
public static synchronized void increate() { //相当于对当前类加锁
i++;
}
public void run() {
for (int c = 0; c < 10000000; c++) {
increate();
}
} public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(new CountStaticMethod());//new一个对象
Thread t2 = new Thread(new CountStaticMethod());//new一个对象
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println(i);
}
}
java同步synchronized的更多相关文章
- 转:Java同步synchronized使用
原文链接 作者:Jakob Jenkov Java 同步块(synchronized block)用来标记方法或者代码块是同步的.Java同步块用来避免竞争.本文介绍以下内容: Java同步关键字(s ...
- Java同步synchronized与死锁
多个线程要操作同一资源时就有可能出现资源的同步问题. 同步就是指多个操作在同一个时间段内只能有一个线程进行,其他线程要等待此线程完成之后才可以继续执行. 解决资源共享的同步操作,可以使用同步代码块和同 ...
- java 同步 synchronized
http://www.cnblogs.com/Qian123/p/5691705.html http://www.cnblogs.com/GnagWang/archive/2011/02/27/196 ...
- Java多线程同步 synchronized 关键字的使用
代表这个方法加锁,相当于不管哪一个线程A每次运行到这个方法时,都要检查有没有其它正在用这个方法的线程B(或者C D等),有的话要等正在使用这个方法的线程B(或者C D)运行完这个方法后再运行此线程A, ...
- Java的synchronized关键字:同步机制总结
JAVA中synchronized关键字能够作为函数的修饰符,也可作为函数内的语句,也就是平时说的同步方法和同步语句块.搞清楚synchronized锁定的是哪个对象,就能帮助我们设计更安全的多线程程 ...
- Java同步块(synchronized block)使用详解
Java 同步块(synchronized block)用来标记方法或者代码块是同步的.Java同步块用来避免竞争.本文介绍以下内容: Java同步关键字(synchronzied) 实例方法同步 静 ...
- 015-线程同步-synchronized几种加锁方式、Java对象头和Monitor、Mutex Lock、JDK1.6对synchronized锁的优化实现
一.synchronized概述基本使用 为确保共享变量不会出现并发问题,通常会对修改共享变量的代码块用synchronized加锁,确保同一时刻只有一个线程在修改共享变量,从而避免并发问题. syn ...
- “全栈2019”Java多线程第十六章:同步synchronized关键字详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...
- Java同步机制总结--synchronized
不久前用到了同步,现在回过头来对JAVA中的同步做个总结,以对前段时间工作的总结和自我技术的条理话.JAVA中synchronized关键字能够 作为函数的修饰符,也可作为函数内的语句,也就是平时说的 ...
随机推荐
- struts2 Action获取表单传值(属性,类))
http://blog.csdn.net/sd0902/article/details/8393157 求大神告知两种方法的不同点 都是写个set方法就行了
- HashSet<T>的妙用
HashSet<int> hs = new HashSet<int>(); var ret = hs.Add(1); //ret==true var ret2 = hs.Ad ...
- 论文笔记--PCN:Real-Time Rotation-Invariant Face Detection with Progressive Calibration Networks
关键词:rotation-invariant face detection, rotation-in-plane, coarse-to-fine 核心概括:该篇文章为中科院计算所智能信息处理重点实验室 ...
- delphi 微信(WeChat)多开源代码
在网上看到一个C++代码示例: 原文地址:http://bbs.pediy.com/thread-217610.htm 觉得这是一个很好的调用 windows api 的示例,故将其转换成了 delp ...
- Microsoft SQL server2017初次安装与使用记录
Microsoft SQL server2017初次安装与使用记录 学校数据库课程以Microsoft SQL server为例, 由于老师给的软件版本和我的window10不兼容,选择官网的最新版2 ...
- Spring Boot消息队列应用实践
消息队列是大型复杂系统解耦利器.本文根据应用广泛的消息队列RabbitMQ,介绍Spring Boot应用程序中队列中间件的开发和应用. 一.RabbitMQ基础 1.RabbitMQ简介 Rabbi ...
- springMVC源码分析--ModelFactory
ModelFactory是用来维护Model的,具体包含两个功能 (1)初始化Model (2)处理器执行后将Model中相应的参数更新到SessionAttributes中 1.初始化Model其实 ...
- MyEclipse的Debug模式启动缓慢
打开breakpoints veiw,右键-> Remove all,重启下服务器就OK了 -–下面有个"顶"字,你懂得O(∩_∩)O哈哈~ -–乐于分享,共同进步! -–更 ...
- linux TCP头部的构造的简单分析
TCP的头部的构造是在函数tcp_transmit_skb()中进行的 函数片段如下: /* Build TCP header and checksum it. */ th = tcp_hdr(skb ...
- Programming In Scala笔记-第十六章、Scala中的List
本章主要分析Scala中List的用法,List上可进行的操作,以及需要注意的地方. 一.List字面量 首先看几个List的示例. val fruit = List("apples&quo ...