同步关键词synchronized
概述
synchronized是java中的一个关键字,也就是说是Java语言内置的特性。
synchronized( 一个任意的对象(锁) ){
代码块中放操作共享数据的代码。
}
public synchronized int getIndex() {
return 1;
}
public static synchronized int getNext() {
return 2;
}
public int getPre() {
//这里的参数可以用java所有对象
//synchronized(this) {
//synchronized(Demo1.class) {
synchronized(new Demo1()) {
System.out.println("synchronized(这里的参数可以用java所有对象)");
}
return 0;
}
synchronized 放在普通方法上,内置锁就是当前类的实例。
synchronized 放在静态方法上,内置锁就是当前类的Class字节码对象
如果一个代码块被synchronized修饰了,当一个线程获取了对应的锁,并执行该代码块时,其他线程便只能一直等待,等待获取锁的线程释放锁。这种特性又被称为互斥锁
而这里获取锁的线程释放锁只会有两种情况:
1)获取锁的线程执行完了该代码块,然后线程释放对锁的占有。
2)线程执行发生异常,此时JVM会让线程自动释放锁。
实例
继续卖火车票的例子。
在《Java中Runnable和Thread的区别》火车票例子里,我们看到三个窗口卖出去的火车票,顺序是乱的。
如何使顺序有序呢?
线程执行的时候,一个个执行不就有序了。即线程1在执行的时候,其他线程阻塞不要执行。
加synchronize。
package multithreading.sync;
public class MyThreadWithImplements implements Runnable {
private int tickets = 10;
@Override
public synchronized void run() {
for (int i = 0; i <= 100; i++) {
if(tickets>0){
System.out.println(Thread.currentThread().getName()+"--卖出票:" + tickets--);
}
}
}
public static void main(String[] args) {
MyThreadWithImplements myRunnable = new MyThreadWithImplements();
Thread thread1 = new Thread(myRunnable, "窗口一");
Thread thread2 = new Thread(myRunnable, "窗口二");
Thread thread3 = new Thread(myRunnable, "窗口三");
thread1.start();
thread2.start();
thread3.start();
}
}
运行结果
窗口一--卖出票:10
窗口一--卖出票:9
窗口一--卖出票:8
窗口一--卖出票:7
窗口一--卖出票:6
窗口一--卖出票:5
窗口一--卖出票:4
窗口一--卖出票:3
窗口一--卖出票:2
窗口一--卖出票:1
缺陷
例子1
如果这个获取锁的线程由于要等待IO或者其他原因(比如调用sleep方法)被阻塞了,但是又没有释放锁,其他线程便只能干巴巴地等待,这多么影响程序执行效率。
因此就需要有一种机制可以不让等待的线程一直无期限地等待下去(比如只等待一定的时间或者能够响应中断),通过Lock就可以办到。
例子2
当有多个线程读写文件时,读写操作会发生冲突现象,写写操作会发生冲突现象,但是读读操作不会发生冲突现象。
但是采用synchronized关键字来实现同步的话,就会导致一个问题:
如果多个线程都只是进行读操作,当一个线程在进行读操作时,其他线程只能等待无法进行读操作。
因此就需要一种机制来使得多个线程都只是进行读操作时,线程之间不会发生冲突,通过Lock就可以办到。
另外,通过Lock可以知道线程有没有成功获取到锁。这个是synchronized无法办到的。
总的来说,也就是说Lock提供了比synchronized更多的功能。
同步关键词synchronized的更多相关文章
- java多线程学习-同步(synchronized)
(示例都是网上视频的) 假如两个线程同时调用一个方法输出字符串 public class SynchronizedTest extends Thread { public static void ma ...
- 同步关键字synchronized
同步关键字synchronized 同步关键字synchronized使用简洁,代码可维护性好.在JDK6中,性能也比早期的JDK有很大的改进.如果可以满足程序要求,应该首先考虑这种同步方式. 关键字 ...
- java多线程——同步块synchronized详解
Java 同步块(synchronized block)用来标记方法或者代码块是同步的.Java同步块用来避免竞争.本文介绍以下内容: Java同步关键字(synchronzied) 实例方法同步 静 ...
- java 为什么wait(),notify(),notifyAll()必须在同步(Synchronized)方法/代码块中调用?
wait()作用:该方法用来将当前线程置入休眠状态,直到接到通知或被中断为止.条件:在调用wait()之前,线程必须要获得该对象的对象级别锁,即只能在同步方法或同步块中调用wait()方法.进入wai ...
- Java基础-多线程-③线程同步之synchronized
使用线程同步解决多线程安全问题 上一篇 Java基础-多线程-②多线程的安全问题 中我们说到多线程可能引发的安全问题,原因在于多个线程共享了数据,且一个线程在操作(多为写操作)数据的过程中,另一个线程 ...
- Java:多线程,线程同步,synchronized关键字的用法(同步代码块、非静态同步方法、静态同步方法)
关于线程的同步,可以使用synchronized关键字,或者是使用JDK 5中提供的java.util.concurrent.lock包中的Lock对象.本文探讨synchronized关键字. sy ...
- 线程的同步之Synchronized的使用
一.介绍 线程的同步:一般的并发指的就是多个线程访问同一份资源.多个线程同时访问(修改)同一份资源的话,就会有可能造成资源数据有误. 如果多个线程访问多个不同资源,就不会造成线程同 ...
- 多线程--同步--方法块和同步块synchronized
package com.sxt.syn; /** * 线程安全: 在并发时保证数据的正确性.效率尽可能高 * synchronized * 1.同步方法 * 2.同步块 * * */ public c ...
- 同步块:synchronized(同步监视器对象){同步运行代码片段}
package seday10; import seday03.Test2; /** * @author xingsir * 同步块:synchronized(同步监视器对象){需要同步运行的代码片段 ...
随机推荐
- SQL Server 数据库启动过程(用户数据库加载过程的疑难杂症)
前言 本篇主要是上一篇文章的补充篇,上一篇我们介绍了SQL Server服务启动过程所遇到的一些问题和解决方法,可点击查看,我们此篇主要介绍的是SQL Server启动过程中关于用户数据库加载的流程, ...
- 长乐国庆集训Day1
T1 统计数字 题目 [题目描述] 设 S(N ) 表示 N 的各位数字之和,如 S(484) = 4+8+4 = 16, S(22) = 2+2 = 4. 如果一个正整数满足 S(x*x) = S( ...
- PHP下载远程图片到本地的几种方法总结(tp5.1)
1.CURL 2.使用file_get_contents 3.使用fopen 参考链接:https://www.jb51.net/article/110615.htm
- centos设置IP
centos设置IP 原由:虚拟机里安装了很多软件,每天要使用,原来使用的动态IP,而且很长时间也没变,一直使用的很好,忽然一天访问不了了,找了几次才发现动态IP地址变了,这些后决定将虚拟机的IP地址 ...
- redis源码分析(四)--aof持久化
Redis aof持久化 Redis支持两种持久化方式:rdb与aof,上一篇文章中已经大致介绍了rdb的持久化实现,这篇文章主要介绍aof实现. 与rdb方式相比,aof会使用更多的存储空间,因为它 ...
- Selenium+Java(十)Selenium常用方法
前言: 通过前几篇博客的已经了解了元素如何定位,提示框下拉框如何处理,多表单,鼠标键盘操作.此篇博客来介绍拿到想应的driver对象后如果对于对象做一些操作. get //打开网站 driver.ge ...
- Bash速查表
例 #!/usr/bin/env bash NAME="John" echo "Hello $NAME!" 变量 NAME="John" e ...
- mapreduce课堂测试结果
package mapreduce; import java.io.IOException; import java.util.StringTokenizer; import org.apache.h ...
- 高性能Golang研讨会【精】
by Dave Cheney 概观 本次研讨会的目标是为您提供诊断Go应用程序中的性能问题并进行修复所需的工具. 通过这一天,我们将从小工作 - 学习如何编写基准,然后分析一小段代码.然后走出去讨论执 ...
- [转]Go语言string,int,int64 ,float之间类型转换方法
1 正文 (1)int转string s := strconv.Itoa(i) 等价于s := strconv.FormatInt(int64(i), 10) (2)int64转string i := ...