同步的前提:

  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. hadoop中mapreduce的mapper抽象类和reduce抽象类

    mapreduce过程key 和value分别存什么值 https://blog.csdn.net/csdnliuxin123524/article/details/80191199 Mapper抽象 ...

  2. equals区别==

    来自:https://blog.csdn.net/m0_37721946/article/details/78405595 java中的数据类型,可分为两类: 1.基本数据类型 byte,short, ...

  3. day07作业猜年龄游戏

    # 给定年龄,用户可以猜三次年龄 # # 年龄猜对,让用户选择两次奖励 # # 用户选择两次奖励后退出 get_prize_dict = {} # 获取的奖品信息 age = 18 inp_count ...

  4. python学习笔记(五)文件操作和集合

    文件基本操作: 现有文件file.txt f=open('file.txt','r')#以只读方式打开一个文件,获取文件的句柄,如果是读的话,r可以不写,默认就是只读:文件不存在时,会报错 first ...

  5. Java线程通信-生产者消费者问题

    线程通信示例——生产者消费者问题 这类问题描述了一种情况,假设仓库中只能存放一件产品,生产者将生产出来的产品放入仓库,消费者将仓库中的产品取走消费.假设仓库中没有产品,则生产者可以将 产品放入仓库,有 ...

  6. PHP curl_getinfo函数

    curl_getinfo — 获取一个cURL连接资源句柄的信息 说明 mixed curl_getinfo ( resource $ch [, int $opt = 0 ] ) 获取最后一次传输的相 ...

  7. 4412 linux延时和时间

    基本知识 • linux中延时函数很简单,却经常用到• 在操作系统中和单片机处理延时方式就完全不一样了,不可能是使用for循环浪费系统资源.而是有专门的接口函数• linux系统编程中常用的延时函数: ...

  8. BZOJ 4238 电压 解题报告

    BZOJ 4238 电压 考虑一条边成为答案以后,删去Ta后剩下的图是一个或很多个二分图,即没有奇环 则一条边可以成为答案,当且仅当自己在所有奇环的交上且不在偶环上. 考虑建出dfs树,那么返祖边一定 ...

  9. Linux0.11内核源码——内核态线程(进程)切换的实现

    以fork()函数为例,分析内核态进程切换的实现 首先在用户态的某个进程中执行了fork()函数 fork引发中断,切入内核,内核栈绑定用户栈 首先分析五段论中的第一段: 中断入口:先把相关寄存器压栈 ...

  10. 查看电脑的s/n序列号信息方式

    要是品牌机的话,通常在机箱的背部或是侧面都会有个不干胶贴纸,上面就有写机器的S/N号 或 点击开始——运行——输入CMD,单击确定 输入:wmic bios get serialnumber 查看本机 ...