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的更多相关文章

  1. 转:Java同步synchronized使用

    原文链接 作者:Jakob Jenkov Java 同步块(synchronized block)用来标记方法或者代码块是同步的.Java同步块用来避免竞争.本文介绍以下内容: Java同步关键字(s ...

  2. Java同步synchronized与死锁

    多个线程要操作同一资源时就有可能出现资源的同步问题. 同步就是指多个操作在同一个时间段内只能有一个线程进行,其他线程要等待此线程完成之后才可以继续执行. 解决资源共享的同步操作,可以使用同步代码块和同 ...

  3. java 同步 synchronized

    http://www.cnblogs.com/Qian123/p/5691705.html http://www.cnblogs.com/GnagWang/archive/2011/02/27/196 ...

  4. Java多线程同步 synchronized 关键字的使用

    代表这个方法加锁,相当于不管哪一个线程A每次运行到这个方法时,都要检查有没有其它正在用这个方法的线程B(或者C D等),有的话要等正在使用这个方法的线程B(或者C D)运行完这个方法后再运行此线程A, ...

  5. Java的synchronized关键字:同步机制总结

    JAVA中synchronized关键字能够作为函数的修饰符,也可作为函数内的语句,也就是平时说的同步方法和同步语句块.搞清楚synchronized锁定的是哪个对象,就能帮助我们设计更安全的多线程程 ...

  6. Java同步块(synchronized block)使用详解

    Java 同步块(synchronized block)用来标记方法或者代码块是同步的.Java同步块用来避免竞争.本文介绍以下内容: Java同步关键字(synchronzied) 实例方法同步 静 ...

  7. 015-线程同步-synchronized几种加锁方式、Java对象头和Monitor、Mutex Lock、JDK1.6对synchronized锁的优化实现

    一.synchronized概述基本使用 为确保共享变量不会出现并发问题,通常会对修改共享变量的代码块用synchronized加锁,确保同一时刻只有一个线程在修改共享变量,从而避免并发问题. syn ...

  8. “全栈2019”Java多线程第十六章:同步synchronized关键字详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...

  9. Java同步机制总结--synchronized

    不久前用到了同步,现在回过头来对JAVA中的同步做个总结,以对前段时间工作的总结和自我技术的条理话.JAVA中synchronized关键字能够 作为函数的修饰符,也可作为函数内的语句,也就是平时说的 ...

随机推荐

  1. vue开发中遇到的问题集锦(2)

    1,在搭建了一个vue的脚手架之后,写了第一个组件,路由也已经配置完毕,且页面的路由显示是:http://localhost:8080/#/userLogin,userLogin里面有内容,但是页面显 ...

  2. C# 基础问答

    1.静态变量和非静态变量的区别? 2.const 和 static readonly 区别? 3.extern 是什么意思? 4.abstract 是什么意思? 5.internal 修饰符起什么作用 ...

  3. AJAX 向后台发送带 List 集合的对象

    现有基类: public class School { int name; int address; List<Student> students = new ArrayList<S ...

  4. centos 7 安装nvidia显卡驱动

    How to install Nvidia drivers in CentOS 7 - Tutorial :  http://www.dedoimedo.com/computers/centos-7- ...

  5. 利用Python进行数据分析——重要的Python库介绍

    利用Python进行数据分析--重要的Python库介绍 一.NumPy 用于数组执行元素级计算及直接对数组执行数学运算 线性代数运算.傅里叶运算.随机数的生成 用于C/C++等代码的集成 二.pan ...

  6. python3中替换python2中cmp函数的新函数分析(lt、le、eq、ne、ge、gt)

    本文地址:http://blog.csdn.net/sushengmiyan/article/details/11332589 作者:sushengmiyan 在python2中我们经常会使用cmp函 ...

  7. [多线程] 生产者消费者模型的BOOST实现

    说明 如果 使用过程中有BUG 一定要告诉我:在下面留言或者给我邮件(sawpara at 126 dot com) 使用boost::thread库来实现生产者消费者模型中的缓冲区! 仓库内最多可以 ...

  8. Dynamics CRM2016 Web API之获取查找字段的text及选项集的text

    本篇再来介绍个web api的功能,关于lookup的text这里只是略带,因为有expand,现有的web api就能实现,主要提的是选项集的text,我们通过基本的查询api查出来的字段值只带有v ...

  9. 前端CSS技术全解(一)

    一.概述 1)用HTML完成样式工作 哪个标签有哪个属性难以记忆 需求变更影响较大(例如像修改成功法则以下的文字颜色需要修改4个地方) <h1 align="center"& ...

  10. MySQL执行插入操作时报错1366 - Incorrect string value

    今天在测试mysql时,发现插入数据的问题,下面和大家分享下解决方法: 首先看问题原因: [Err] 1366 - Incorrect string value: '\xCF\xD6' for col ...