18.synchronized
同步的前提:
- 必须要有两个或者两个以上的线程
- 必须是多个线程使用同一个锁
- 必须保证同步中只能有一个线程在运行
- 好处:解决了多线程的安全问题
- 弊端:多个线程需要判断锁,较为消耗资源、抢锁的资源。
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的更多相关文章
- Java多线程5:synchronized锁方法块
synchronized同步代码块 用关键字synchronized声明方法在某些情况下是有弊端的,比如A线程调用同步方法执行一个较长时间的任务,那么B线程必须等待比较长的时间.这种情况下可以尝试使用 ...
- synchronized锁机制 之 代码块锁(转)
synchronized同步代码块 用关键字synchronized声明方法在某些情况下是有弊端的,比如A线程调用同步方法执行一个较长时间的任务,那么B线程必须等待比较长的时间.这种情况下可以尝试使用 ...
- java 多线程9 : synchronized锁机制 之 代码块锁
synchronized同步代码块 用关键字synchronized声明方法在某些情况下是有弊端的,比如A线程调用同步方法执行一个较长时间的任务,那么B线程必须等待比较长的时间.这种情况下可以尝试使用 ...
- java 多线程系列基础篇(四)之 synchronized关键字
1. synchronized原理 在java中,每一个对象有且仅有一个同步锁.这也意味着,同步锁是依赖于对象而存在.当我们调用某对象的synchronized方法时,就获取了该对象的同步锁.例如,s ...
- Java多线程(三):Synchronized
多线程安全 脏读:多个线程对同一个对象的实例变量进行修改后访问,导致读到的数据是被修改过的. 实例 ThreadDomain16类 public class ThreadDomain16 { priv ...
- Java关键字(八)——synchronized
synchronized 这个关键字,我相信对于并发编程有一定了解的人,一定会特别熟悉,对于一些可能在多线程环境下可能会有并发问题的代码,或者方法,直接加上synchronized,问题就搞定了. 但 ...
- synchronized锁代码块(七)
synchronized同步代码块 用关键字synchronized声明方法在某些情况下是有弊端的,比如A线程调用同步方法执行一个较长时间的任务,那么B线程必须等待比较长的时间.这种情况下可以尝试使用 ...
- To Learn
1. Hybrid:Ionic.Cordova.AngularJS等框架 webView,处理H5 2. View.ViewGroup android.view.View public class ...
- java多线程系类:基础篇:04synchronized关键字
概要 本章,会对synchronized关键字进行介绍.涉及到的内容包括:1. synchronized原理2. synchronized基本规则3. synchronized方法 和 synchro ...
随机推荐
- struts2结果跳转和参数获取
一.结果跳转方式 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC ...
- hive中为分区表增加字段需要注意默认不会修改已有分区的字段,导致查询时新增字段为null
若向hive表添加字段,通常会使用下面这种语句 alter table default.testparquet add columns(c8 string); 但是对于分区表来说, 1. 若新建的分区 ...
- Debian取消从光盘安装软件的方式(please insert the disc labeled)
与Ubuntu不同,使用apt-get install packages时Debian可能会提示: Media change: please insert the disc labeled 'Debi ...
- Idea的几个常用的
sout+tab= "System.out.println()" ctrl+alt+v=生成当前对象的实例 ctrl+shift+enter="(真个是真的牛哦)直接 ...
- Vue学习笔记-作用域插槽
有时候我们希望子组件的内容由父组件决定如何展示,这个时候子组件的数据父组件并不能访问到,而作用域插槽的关键之处就在于,父组件能接收来自子组件的slot传递过来的参数. <div id=" ...
- 在Windows系统使用Gpg4win进行加密解密
GPG,又称为GnuPG,全称是Gnu Private Guard,即GNU隐私卫士.GPG是以PGP算法为核心的强大的加密软件.但GPG项目是一套命令行程序,而且是为 Linux 等开源操作系统设计 ...
- python中遍历列表字典元组
遍历列表,打印:我叫name,今年age岁,家住dizhi,电话phone lt = [ {'name':'小王', 'age':18, 'info':[('phone', '123'), ('diz ...
- hdu 5517 Triple
题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=5517 ------------------------------------------------ ...
- jmeter添加自定义扩展函数之DoubleSum
1,打开eclipse,新建maven工程,在pom中引用jmeter核心jar包,具体请看---https://www.cnblogs.com/guanyf/p/10863033.html---,这 ...
- PHP-Redis扩展安装(四)
PHP-Redis扩展安装(四) 安装环境链接:http://pan.baidu.com/s/1i4IbJox Memecached 服务器安装(一) memcached php扩展(二) redis ...