同步的前提:

  1. 必须要有两个或者两个以上的线程
  2. 必须是多个线程使用同一个锁
  3. 必须保证同步中只能有一个线程在运行
  • 好处:解决了多线程的安全问题
  • 弊端:多个线程需要判断锁,较为消耗资源、抢锁的资源。
import java.util.ArrayList;
import java.util.List; /**
* synchronized 实现线程间的同步,对同步的代码加锁,似的每次只能有一个线程进入同步块
* 可以保证线程间的可见性和有序性
* · 指定加锁对象:对给定对象加锁,进入同步代码前要获取给定对象的锁
* · 直接作用于实例方法:相当于对当前实例加锁,进入同步代码前要获取当前实例的锁
* · 直接作用于静态方法:相当于对当前类加锁,进入同步代码前要获取当前类的锁 -- class文件
*/
public class SynchronizedDemo {
private static int size = 0;
private static List<Integer> arrayOne = new ArrayList<>(10000);
private static List<Integer> arrayTwo = new ArrayList<>(10000);
public static synchronized void increase(){ //synchronized作用于一个实例方法
size++;
}
public static void main(String[] args) throws InterruptedException{ for (int i = 0; i < 10000; i++) {
arrayOne.add(0);
arrayTwo.add(0);
}
Thread threadOne = new Thread(() -> {
int length = arrayOne.size();
for (int i = 0; i < length; i++) {
if (arrayOne.get(i).intValue()==0){
increase();
}
}
});
Thread threadTwo = new Thread(() -> {
int length = arrayTwo.size();
for (int i = 0; i < length; i++) {
if (arrayTwo.get(i).intValue()==0){
increase();
}
}
});
threadOne.start();
threadTwo.start();
threadOne.join();
threadTwo.join();
System.out.println(size);
}
}
import java.util.ArrayList;
import java.util.List; /**
* Runnable
*/
public class SynchronizedDemo1 {
private static int size = 0;
private static List<Integer> arrayOne = new ArrayList<>(10000);
private static List<Integer> arrayTwo = new ArrayList<>(10000); public static class AccountSyncBad implements Runnable{
synchronized void increase(){ //synchronized
size++;
}
@Override
public void run() {
int length = arrayOne.size();
for (int i = 0; i < length; i++) {
if (arrayOne.get(i).intValue()==0){
increase();
}
}
}
}
public static void main(String[] args) throws InterruptedException{
for (int i = 0; i < 10000; i++) {
arrayOne.add(0);
arrayTwo.add(0);
}
AccountSyncBad accountSyncBad = new AccountSyncBad();
Thread threadOne = new Thread(accountSyncBad);
Thread threadTwo = new Thread(accountSyncBad);
threadOne.start();
threadTwo.start();
threadOne.join();
threadTwo.join();
System.out.println(size);
}
}
import java.util.ArrayList;
import java.util.List; /**
* 两个线程指向不同的Runnable实例,这两个线程使用的是两把不同的锁,无法保证线程安全
*/
public class SynchronizedDemo2 {
private static int size = 0;
private static List<Integer> arrayOne = new ArrayList<>(10000);
private static List<Integer> arrayTwo = new ArrayList<>(10000); public static class AccountSyncBad implements Runnable{
synchronized void increase(){ //synchronized
size++;
}
// static synchronized void increase(){ //修改为static,这样即使两个线程指向不同的Runnable,但请求的是当前类的锁,因此可以正确同步
// size++;
// }
@Override
public void run() {
int length = arrayOne.size();
for (int i = 0; i < length; i++) {
if (arrayOne.get(i).intValue()==0){
increase();
}
}
}
}
public static void main(String[] args) throws InterruptedException{
for (int i = 0; i < 10000; i++) {
arrayOne.add(0);
arrayTwo.add(0);
}
Thread threadOne = new Thread(new AccountSyncBad());
Thread threadTwo = new Thread(new AccountSyncBad());
threadOne.start();
threadTwo.start();
threadOne.join();
threadTwo.join();
System.out.println(size);
}
}

18.synchronized的更多相关文章

  1. Java多线程5:synchronized锁方法块

    synchronized同步代码块 用关键字synchronized声明方法在某些情况下是有弊端的,比如A线程调用同步方法执行一个较长时间的任务,那么B线程必须等待比较长的时间.这种情况下可以尝试使用 ...

  2. synchronized锁机制 之 代码块锁(转)

    synchronized同步代码块 用关键字synchronized声明方法在某些情况下是有弊端的,比如A线程调用同步方法执行一个较长时间的任务,那么B线程必须等待比较长的时间.这种情况下可以尝试使用 ...

  3. java 多线程9 : synchronized锁机制 之 代码块锁

    synchronized同步代码块 用关键字synchronized声明方法在某些情况下是有弊端的,比如A线程调用同步方法执行一个较长时间的任务,那么B线程必须等待比较长的时间.这种情况下可以尝试使用 ...

  4. java 多线程系列基础篇(四)之 synchronized关键字

    1. synchronized原理 在java中,每一个对象有且仅有一个同步锁.这也意味着,同步锁是依赖于对象而存在.当我们调用某对象的synchronized方法时,就获取了该对象的同步锁.例如,s ...

  5. Java多线程(三):Synchronized

    多线程安全 脏读:多个线程对同一个对象的实例变量进行修改后访问,导致读到的数据是被修改过的. 实例 ThreadDomain16类 public class ThreadDomain16 { priv ...

  6. Java关键字(八)——synchronized

    synchronized 这个关键字,我相信对于并发编程有一定了解的人,一定会特别熟悉,对于一些可能在多线程环境下可能会有并发问题的代码,或者方法,直接加上synchronized,问题就搞定了. 但 ...

  7. synchronized锁代码块(七)

    synchronized同步代码块 用关键字synchronized声明方法在某些情况下是有弊端的,比如A线程调用同步方法执行一个较长时间的任务,那么B线程必须等待比较长的时间.这种情况下可以尝试使用 ...

  8. To Learn

    1. Hybrid:Ionic.Cordova.AngularJS等框架 webView,处理H5 2. View.ViewGroup android.view.View  public class ...

  9. java多线程系类:基础篇:04synchronized关键字

    概要 本章,会对synchronized关键字进行介绍.涉及到的内容包括:1. synchronized原理2. synchronized基本规则3. synchronized方法 和 synchro ...

随机推荐

  1. 前端每日实战:65# 视频演示如何用纯 CSS 创作一个摇摇晃晃的 loader

    效果预览 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览.https://codepen.io/comehope/pen/oyJvpe 可交互视频 此视频是可以 ...

  2. HTML知识梳理(笔记)

    HTML常见元素 meta 定义和用法<meta> 元素可提供有关页面的元信息(meta-information),比如针对搜索引擎和更新频度的描述和关键词. <meta> 标 ...

  3. tensorflow的boolean_mask函数

    在mask中定义true,保留与其进行运算的tensor里的部分内容,相当于投影的功能. mask与tensor的维度可以不相同的,但是对应的长度一定要相同,也就是要有一一对应的部分: 结果的维度 = ...

  4. 多任务Multitask Learning

    一次只学习一个任务,大部分机器学习都属于单任务学习. 多任务学习:把多个相关的任务放在一起学习,同时学习多个任务. 对于复杂的问题,可以分解为简单的相互独立的子问题来解决,然后再合并结果,得到最初复杂 ...

  5. HashMap的底层原理 cr:csdn:zhangshixi

    1.    HashMap概述: HashMap是基于哈希表的Map接口的非同步实现.此实现提供所有可选的映射操作,并允许使用null值和null键.此类不保证映射的顺序,特别是它不保证该顺序恒久不变 ...

  6. 杂项-报表-Minitab:Minitab百科

    ylbtech-杂项-报表-Minitab:Minitab百科 Minitab软件是现代质量管理统计的领先者,全球六西格玛实施的共同语言,以无可比拟的强大功能和简易的可视化操作深受广大质量学者和统计专 ...

  7. 前端模块化开发的价值(seaJs)

    随着互联网的飞速发展,前端开发越来越复杂.本文将从实际项目中遇到的问题出发,讲述模块化能解决哪些问题,以及如何使用 Sea.js 进行前端的模块化开发. 恼人的命名冲突 我们从一个简单的习惯出发.我做 ...

  8. QTP与QC整合

    QC-QTP整合 在本节中,我们将学习如何将QTP和QC整合.通过整合,在QTP自动化脚本可以直接从Quality Center执行.建立连接,第一个步骤是安装所需的加载项.我们将了解如何通过采取样品 ...

  9. MSF——基本使用和Exploit模块(一)

    MSF系列: MSF——基本使用和Exploit模块(一) MSF——Payload模块(二) MSF——Meterpreter(三) MSF——信息收集(四) MSF——Metasploit Fra ...

  10. JNDI 笔记

    原理:         在DataSource中事先建立多个数据库连接,保存在数据库连接池中.当程序访问数据库时,只用从连接池中取空闲状态的数据库连接即可,访问结束,销毁资源,数据库连接重新回到连接池 ...