同步关键词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(同步监视器对象){需要同步运行的代码片段 ...
随机推荐
- Emiya 家今天的饭
\(dp_{i,j,k}\)表示前\(i\)种烹饪方法,假设最多的是食材\(j\),食材\(j\)比其他食材多\(k\)次出现 其中\(i \in [1,n],j \in [1,m],k \in [- ...
- jquery下拉单选框可左右移动数据
<!doctype html> <html> <head> <meta charset="utf-8"> <title> ...
- lambd
匿名函数 1.匿名函数格式 void test01() { []() { cout << "hello world" << endl; }(); } 2使用 ...
- Mysql批量更新的三种方式
前言 批量插入由于mysql的VALUES原生支持,使用较为便利. 批量更新的写法一般有三种,在更新数量较少的情况下,前两种性能不相上下.但是在更新字段增加,更新条数较多(500以上)建议使用第三种写 ...
- 阿里巴巴 Java 开发手册(二): 常量定义
1. [强制]不允许任何魔法值(即未经定义的常量)直接出现在代码中. 反例: String key = "Id#taobao_" + tradeId; cache.put(key, ...
- Udp客户端与服务通讯
使用UDP与服务端通讯时候,同样需要先启用udp服务端监控,当服务端启动成功,在启动客户端 首先UDP服务端类,代码如下: public class UdpServerTest { public vo ...
- 用HTML、CSS、JS制作圆形进度条(无动画效果)
逻辑 1.首先有一个圆:蓝色的纯净的圆,效果: 2.再来两个半圆,左边一个,右边一个将此蓝色的圆盖住,效果: 此时将右半圆旋转60°,就会漏出底圆,效果: 然后我们再用一个比底圆小的圆去覆盖这个大 ...
- Spring通过注解@Autowired/@Resource获取bean实例时为什么可以直接获取接口而不是注入的类
问: 这个问题困扰了我好久,一直疑问这个接口的bean是怎么注入进去的?因为只看到使用@Service注入了实现类serviceImpl,使用时怎么却获取的接口,而且还能调用到实现类的方法,难道这个接 ...
- springboot中modbus使用
pom.xml配置: false true ias-snapshots Infinite Automation Snapshot Repository true false ias-releases ...
- POSIX多线程
全文共分四部分: POSIX多线程—概述 POSIX多线程—异步编程举例 POSIX多线程—线程基本概念 POSIX多线程—互斥量概述 POSIX多线程—概述 Content 1. ...