同步关键词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(同步监视器对象){需要同步运行的代码片段 ...
随机推荐
- Juju solutions for OpenStack
Juju solutions for OpenStack Juju makes it easy to deploy OpenStack at scale. Quickly and reliably b ...
- Git_从远程branch取回所有最新代码,暴力覆盖本地 && GIT基本结构
假设你本地有一个xx分支对应着远端的xx分支,当前,你在本地的xx分支进行了修改(可以是执行了add, commit,但不要push),然后,现在想从远端的xx分支拿到最新的代码,可以用下图方法覆盖掉 ...
- SQL Server sp_monitor使用
SQL Server提供了sp_monitor存储过程可以方便我们查看SQL Server性能统计信息,包括CPU/Network/IO,通过这些信息可以对自己的数据库性能状况有一个大致的了解. 下面 ...
- 微信配置JS接口安全域名问题-Nginx配置
1.将下载的txt文件放入/usr/local/nginx/html/目录下面. 2.修改nginx.cong配置文件中的location标签 location / { root html; inde ...
- python_并发与通信
独立的进程内存空间与共享的服务器进程空间 知识点一: 进程间通信的限制 进程是独立的,互不干扰的独立内存空间我们想不能修改变量但是,深层次问题是,这个进程与那个进程完全失去了联系 import mul ...
- sleep方法动态打印 C语言
#include<Windows.h> #include<stdio.h> #include<stdlib.h> #include<string.h> ...
- Deployment.spec.selector.matchLables实验解释
原文:https://cloud.tencent.com/developer/article/1394657 Deployment.spec.selector.matchLables实验解释 作者: ...
- springboot 接口参数校验
前言 在开发接口的时候,参数校验是必不可少的.参数的类型,长度等规则,在开发初期都应该由产品经理或者技术负责人等来约定.如果不对入参做校验,很有可能会因为一些不合法的参数而导致系统出现异常. 上一篇文 ...
- 2019三六零 java面试笔试题 (含面试题解析)
本人3年开发经验.18年年底开始跑路找工作,在互联网寒冬下成功拿到阿里巴巴.今日头条.360等公司offer,岗位是Java后端开发,最终选择去了三六零. 面试了很多家公司,感觉大部分公司考察的点都差 ...
- Java 缓存实例
重复创建相同的对象没有太大的意义,反而加大了系统开销,某些情况下,可以缓存该类的实例,实现复用. 实现缓存实例:定义一个private static成员变量存储类的实例(多个可用数组)先检测上面的成员 ...