-
2021-02-26 17:43:31
Java多线程的同步代码块
synchronized(对象){
需要同步的代码
}
同步代码块可以解决安全问题的根本原因在于那个对象快上,这个对象如同锁的功能。
多个线程需要同一个锁,才能锁的住,所以这个对象需要在run()方法外面声明。
同步的特点:1,多线程,2,多线程使用同一个锁 3,能解决线程安全的问题。
同步的弊端:当线程很多时,其他线程会等待正在执行的线程执行完毕,这样会浪费资源,
降低CUP的使用效率。
虽然synchronized可以实现锁的功能,但是为了更清晰的表达如何加锁和解锁,JDK5以后提供了
一个新的锁对象,lock
Lock
void lock (); 获取锁
void unlock();释放锁
Reentrantlock 是lock的实现类。
lock loc=new Reentrantlock ();
try{
loc.lock();{
// 要锁的代码
}
finally{
loc.unlock();
}
同步的弊端:效率低,如果出现了嵌套,就容易出现死锁。
死锁:2个或2个以上的线程在争夺资源中,发生了相互等待的现象。
死锁举例:
flag =1;
public void run (){
if( flag){
synchronized(A){
synchronized(B);
}
}
else {
synchronized(B){
synchronized(A);
}
}
}
}
更多相关内容 -
java中synchronized(同步代码块和同步方法)详解及区别
2020-08-31 06:27:57主要介绍了 java中synchronized(同步代码块和同步方法)详解及区别的相关资料,需要的朋友可以参考下 -
Java同步代码块和同步方法原理与应用案例详解
2020-08-25 12:25:44主要介绍了Java同步代码块和同步方法原理与应用,结合具体案例形式分析了使用java同步代码块和同步方法实现买票功能的相关原理与操作技巧,需要的朋友可以参考下 -
Java同步代码块解决银行取钱的安全问题实例分析
2020-08-25 17:15:35主要介绍了Java同步代码块解决银行取钱的安全问题,结合实例形式分析了java基于线程的同步问题实现与使用相关操作技巧,需要的朋友可以参考下 -
同步代码块
2020-02-06 10:49:40同步代码块 1.什么情况下需要同步 当多线程并发,有多段代码同时执行时,我们希望某一段代码执行的过程中CPU不要切换到其他线程工作,这时就需要同步。 如果两段代码是同步的,那么同一时间只能执行一段,在一段...同步代码块
- 1.什么情况下需要同步
- 当多线程并发,有多段代码同时执行时,我们希望某一段代码执行的过程中CPU不要切换到其他线程工作,这时就需要同步。
- 如果两段代码是同步的,那么同一时间只能执行一段,在一段代码没执行结束之前,不会执行另外一段代码。
- 2.同步代码块
- 使用synchronized关键字加上一个锁对象来定义一段代码,这就叫同步代码块。
- 多个同步代码块如果使用相同的锁对象,那么他们就是同步的。
package com.heima.syn; public class Demo01_Synchronized { public static void main(String[] args) { final Printer p = new Printer(); new Thread() { public void run() { while(true) { p.print1(); } } }.start(); new Thread() { public void run() { while(true) { p.print2(); } } }.start(); } } class Printer { //锁对象可以是任意对象,但是被锁的代码需要保证是同一把锁,不能用匿名对象 Demo d = new Demo(); public void print1() { //同步代码块,锁机制,锁对象可以是任意的 //synchronized(new Demo()) { synchronized(d) { System.out.print("黑"); System.out.print("马"); System.out.print("程"); System.out.print("序"); System.out.print("员"); System.out.print("\r\n"); } } public void print2() { //锁对象不能用匿名对象,因为匿名对象不是同一个对象 //synchronized(new Demo()) { synchronized(d) { System.out.print("传"); System.out.print("智"); System.out.print("播"); System.out.print("客"); System.out.print("\r\n"); } } } class Demo{}
- 1.什么情况下需要同步
-
java 中同步方法和同步代码块的区别详解
2020-08-31 07:20:08主要介绍了java 中同步方法和同步代码块的区别是什么的相关资料,需要的朋友可以参考下 -
Java 多线程 —— 同步代码块(解决线程安全问题)
2021-10-23 19:59:26目录火车站抢票问题同步代码块同步方法(this锁)同步方法,在public的后面加上synchronized关键字this锁静态同步方法 火车站抢票问题 由于现实中买票也不会是零延迟的,为了真实性加入了延迟机制,也就是线程休眠...火车站抢票问题
由于现实中买票也不会是零延迟的,为了真实性加入了延迟机制,也就是线程休眠语句
package test.MyThread.ticketDemo; public class RunnableThread implements Runnable{ private int ticket = 100; @Override public void run(){ while(true){ if(ticket>0){ try { Thread.sleep(100); //语句一 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"正在出售第 "+ticket+" 张票"); //语句二 ticket--; //语句三 } } } }
package test.MyThread.ticketDemo; public class ticketDemo1 { public static void main(String[] args) { RunnableThread r1 = new RunnableThread(); Thread t1 = new Thread(r1,"窗口一"); Thread t2 = new Thread(r1,"窗口二"); Thread t3 = new Thread(r1,"窗口三"); t1.start(); t2.start(); t3.start(); } }
但是结果和我们想象中的不一样,三个窗口卖出了同样的票这是因为,CPU的操作具有原子性,单独执行一条指令或者说语句,在执行完毕前不会被中断。
三个线程被启动后,都会处于就绪状态,然后开始抢夺CPU执行语句。- 语句一:Thread.sleep(100);
- 语句二: System.out.println(Thread.currentThread().getName()+“正在出售第 “+ticket+” 张票”);
- 语句三: ticket–;
我将程序中需要执行的三条主要语句列了出来
三条线程中,加入线程一先抢到了CPU,这时就会开始执行语句,也就是至少会完成一条语句一,然后进入休眠。注:如果语句一不是休眠语句,而是别的语句,那么线程一就可以继续往下执行,因为原子性,正在执行的语句不会被打断,所以只会在一条语句结束,下一条语句未开始时,被抢走CPU或者中断,导致线程退出运行状态,转为就绪或者阻塞状态。所以线程一可以一次性完成多条语句,也有可能刚完成一条语句就被抢走了CPU。
接着,线程二,线程三也抢到了CPU,也开始执行语句一,然后也进入休眠状态。之后线程一二三从休眠中醒来,开始争抢CPU完成语句二,但是三者都在完成语句三之前被抢走了CPU,导致一直没有执行ticket–语句,ticket也就没有减少,因此三条线程一共打印三条输出语句,里面的ticket都是相同。
然后三条线程又开始争抢CPU来完成语句三,一个线程让ticket减一,三个线程减少三张票。完成语句三后,又开始新的循环,三个线程开始争抢CPU完成语句一。
因此,看到的结果会是,三条语句的ticket都相同,然后ticket突然减三,接着又输出三条ticket相同的输出语句。
那么,该如何解决这种情况呢?
这种延迟卖票的问题被称为线程安全问题,要发生线程安全问题需要满足三个条件(任何一共条件不满足都不会造成线程安全问题):- 是否存在多线程环境
- 是否存在共享数据/共享变量
- 是否有多条语句操作着共享数据/共享变量
火车站延迟卖票问题满足这三个条件,因此造成了线程安全问题,而前两条都不可避免,那么就可以着手于破坏掉第三个条件,让线程安全问题不成立。
思路是将多条语句包装成一个同步代码块,当某个线程执行这个同步代码块的时候,就跟原子性一样,其他的线程不能抢占CPU,只能等这个同步代码块执行完毕。
解决办法:
- synchronized —— 自动锁
- lock —— 手动锁
synchronized
synchronized(对象){ //可能会发生线程安全问题的代码 } //这里的对象可以是任意对象,我们可以用 Object obj = new Object()里面的obj放入括号中
使用synchronized的条件:
- 必须有两个或两个以上的线程
- 同一时间只有一个线程能够执行同步代码块
- 多个线程想要同步时,必须共用同一把锁
synchronized(对象)括号里面的对象就是一把锁
使用synchronized的过程:
- 只有抢到锁的线程才可以执行同步代码块,其余的线程即使抢到了CPU执行权,也只能等待,等待锁的释放。
- 代码执行完毕或者程序抛出异常都会释放锁,然后还未执行同步代码块的线程争抢锁,谁抢到谁就能运行同步代码块。
同步代码块
因此,修改后的代码为:
package test.MyThread.ticketDemo; public class RunnableThread implements Runnable{ private int ticket = 100; Object obj = new Object(); @Override public void run(){ while(true){ synchronized (obj) { if (ticket > 0) { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "正在出售第 " + ticket + " 张票"); ticket--; } } } } }
package test.MyThread.ticketDemo; public class ticketDemo1 { public static void main(String[] args) { //这里没有改动,只是在上一个代码中加了一把锁 RunnableThread r1 = new RunnableThread(); Thread t1 = new Thread(r1,"窗口一"); Thread t2 = new Thread(r1,"窗口二"); Thread t3 = new Thread(r1,"窗口三"); t1.start(); t2.start(); t3.start(); } }
可以看出来结果符合我们的预期,是正确的现在又有了新的问题,那就是如果我在构造线程的RunnableThread类里面加入方法呢?同步代码块里面出现方法时,我们应该怎么“上锁”呢?
同步方法(this锁)
同步方法,在public的后面加上synchronized关键字
package test.MyThread.ticketDemo; public class RunnableThread1 implements Runnable{ private int ticket = 100; Object obj = new Object(); public boolean flag = true; @Override public void run(){ if(flag==true){ while(ticket>0){ try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } SellTicket1(); } } } //同步方法,在public的后面加上synchronized关键字 public synchronized void SellTicket1(){ if(ticket>0){ System.out.println(Thread.currentThread().getName()+"正在出售第 "+ticket+" 张票"); ticket--; } } }
package test.MyThread.ticketDemo; public class ticketDemo2 { public static void main(String[] args) throws InterruptedException { RunnableThread1 r = new RunnableThread1(); Thread t1 = new Thread(r,"窗口一"); Thread t2 = new Thread(r,"窗口二"); t1.start(); t2.start(); } }
this锁
先来看看,如果有两条路径,一条路径是使用同步代码块,但是对象是obj,另一条路径是使用同步方法
package test.MyThread.ticketDemo; public class TicketWindow2 implements Runnable{ //定义100张票 private static int tickets = 100; Object obj = new Object(); int i =0; @Override public void run() { while (true){ if(i%2==0){ synchronized (obj){ if(tickets>0){ try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+" 正在出售第 "+(tickets--)+" 张票"); } } }else { sellTicket(); } i++; } } public synchronized void sellTicket(){ if(tickets>0){ try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+" 正在出售第 "+(tickets--)+" 张票"); } } }
结果出错,说明同步方法的用的对象锁不能是任意的对象,不同的线程应该用相同的锁。同步方法是属于对象,而在这个类里面调用方法的是this对象,也就是this.sellTicket(),因此把this提取出来作为对象锁中的对象。这样多个线程都用的是this锁package test.MyThread.ticketDemo; public class TicketWindow2 implements Runnable{ //定义100张票 private static int tickets = 100; Object obj = new Object(); int i =0; @Override public void run() { while (true){ if(i%2==0){ synchronized (this){ if(tickets>0){ try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+" 正在出售第 "+(tickets--)+" 张票"); } } }else { sellTicket(); } i++; } } public synchronized void sellTicket(){ if(tickets>0){ try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+" 正在出售第 "+(tickets--)+" 张票"); } } }
修改完成后再运行代码,发现没有错误
注:
- 一个线程使用同步方法,另一个线程使用同步代码块this锁,可以实现同步
- 一个线程使用同步方法,另一个线程使用同步代码块,但是不是this锁。这种情况不能实现同步。
静态同步方法
同步方法的锁对象是this,
静态同步方法的锁对象是:这个静态同步方法所属的类的字节码文件下面代码挺长的,但其实就修改了上面同步方法的代码的两处地方
- public synchronized void sellTicket(){}改为
public synchronized static void sellTicket(){} - synchronized (this){}改为synchronized (TicketWindow2.class){}
package test.MyThread.ticketDemo; public class TicketWindow2 implements Runnable{ //定义100张票 private static int tickets = 100; Object obj = new Object(); int i =0; @Override public void run() { while (true){ if(i%2==0){ synchronized (TicketWindow2.class){ if(tickets>0){ try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+" 正在出售第 "+(tickets--)+" 张票"); } } }else { sellTicket(); } i++; } } public synchronized static void sellTicket(){ if(tickets>0){ try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+" 正在出售第 "+(tickets--)+" 张票"); } } }
main()方法里面创建进程和启动进程的代码,和上面同步方法里面的代码相同
结果也和上面的一样,都不再列出来了死锁问题
package test.MyThread.ticketDemo; //两个不同的锁对象 public class LockObject { public static final Object lock1 = new Object(); public static final Object lock2 = new Object(); }
package test.MyThread.ticketDemo; public class DieLockThread extends Thread{ public boolean flag; public DieLockThread(boolean flag){ this.flag = flag; } @Override public void run() { if(flag){ synchronized(LockObject.lock1){ System.out.println("lock1"); synchronized(LockObject.lock2){ System.out.println("lock2"); } } }else{ synchronized(LockObject.lock2){ System.out.println("lock2"); synchronized(LockObject.lock1){ System.out.println("lock1"); } } } } }
package test.MyThread.ticketDemo; public class DieLockDemo { public static void main(String[] args) { DieLockThread d1 = new DieLockThread(true); DieLockThread d2 = new DieLockThread(false); d1.start(); d2.start(); } }
程序会卡在这一步,不能进行下一步也不能停止
利用有参构造,构造出来的线程d1应该是先获得锁对象LockObject.lock1然后执行打印语句。接着获取锁对象LockObject.lock2,然后打印lock2。
但是这里因为线程d2是先获取的锁对象LockObject.lock2,并占据这个锁对象,然后想获得锁对象LockObject.lock1,但LockObject.lock1此时被线程d1占据着两个线程都在等待对方释放锁对象,然后进行下一步,但是两者都不释放,导致程序卡死在这里。这就造成了死锁。
lock
package test.MyThread.ticketDemo; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class LockThread implements Runnable{ private int ticket = 100; Lock lock = new ReentrantLock(); @Override public void run(){ while(ticket>0){ try{ lock.lock(); if(ticket>0){ try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " 正在出售第 " + (ticket--) + " 张票"); } }finally { lock.unlock(); } } } }
package test.MyThread.ticketDemo; public class LockDemo { public static void main(String[] args) { LockThread lt = new LockThread(); Thread t1 = new Thread(lt,"窗口一"); Thread t2 = new Thread(lt,"窗口二"); Thread t3 = new Thread(lt,"窗口三"); t1.start(); t2.start(); t3.start(); } }
结果正确 -
同步代码块(synchronized).zip
2020-03-22 11:34:22【Java基础知识 第四节 多线程复习】中,同步代码块(synchronized关键字)的两个练习代码。 -
Java使用同步代码块
2019-05-26 20:25:19为了解决线程安全问题,Java的多线程支持引入了同步监视器来解决这个问题,使用 同步监视器的通用方法就是同步代码块。 同步代码块的语法格式如下: synchronized(obj) { //同步代码块 } } obj叫做同步监视...为了解决线程安全问题,Java的多线程支持引入了同步监视器来解决这个问题,使用 同步监视器的通用方法就是同步代码块。
同步代码块的语法格式如下:
synchronized (obj)
{
//同步代码块 }
}
obj叫做同步监视器(即锁对象),任何线程进入下面同步代码块之前必须先获得对obj 的锁;其他线程无法获得锁,也就执行同步代码块。这种做法符合:“加锁修改释放锁”的逻辑。锁对象可以是任意对象,但必须保证是同一对象任何时刻只能有一个线程可以获得对同步监视器的锁定,当同步代码块执行完成后该线程会释放对该同步监视器的锁定。
示例代码:
首先使用一个javaBean类模拟用户账户信息
package com.gx.threaddemo;
import java.io.Serializable;
publicclass Account implements Serializable {
privatestaticfinallongserialVersionUID = 1L;
// 银行账户
private String number;
// 账户余额
privatedoublemoney;
public Account(Stringnumber, double money) {
this.number = number;
this.money = money;
}
public String getNumber(){
returnnumber;
}
publicvoid setNumber(Stringnumber) {
this.number = number;
}
publicdouble getMoney() {
returnmoney;
}
publicvoid setMoney(double money) {
this.money = money;
}
}
创建一个线程类模拟取钱过程
class TakeMoney extends Thread {
// 谁取钱
private String name;
// 账户对象
private Account account;
// 取款金额
privatedoubletakeMoney;
public TakeMoney(Stringname, Account account, double takeMoney) {
this.name = name;
this.account = account;
this.takeMoney = takeMoney;
}
@Override
publicvoid run() {
// 加锁
synchronized (account) {
if (takeMoney <= account.getMoney()) {
System.out.println(this.name + "取钱成功,取出" + takeMoney + "元");
// 线程暂停 10ms 模拟网络传输
try {
sleep(10);
}catch(InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 修改余额
double money = account.getMoney() - takeMoney;
System.out.println("计算余额 = " + money);
account.setMoney(money);
System.out.println("账户:" + account.getNumber() + "余额为: "
+account.getMoney());
}else {
System.out.println(this.name + "取钱失败,原因:" + account.getNumber()
+"账户余额不足!");
}
}
// 同步代码块执行结束,线程释放同步锁
}
}
创建两个线程并运行,模拟AB两人同时取钱情况
package com.gx.threaddemo;
import java.util.Random;
publicclass TakeMoneyDemo {
publicstaticvoid main(String[] args){
Accountaccount = new Account("666666", 5000);
//TakeMoney 使用了同步代码块,不存在安全问题
TakeMoneytakeMoney1 = new TakeMoney("小明", account, 1000);
TakeMoneytakeMoney2 = new TakeMoney("小红", account, 4500);
// 通过随机数,随机先启动某个程序
Randomrandom = new Random();
int randmoInt =random.nextInt(100);
if (randmoInt % 2 ==0) {
takeMoney1.start();
takeMoney2.start();
}else {
takeMoney2.start();
takeMoney1.start();
}
// 等待子线程结束
try {
Thread.sleep(1000);
}catch(InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(account.getNumber()+ "账户最终余额:" + account.getMoney());
}
}
代码执行结果如下,这样就不会出现超取的情况:
-
同步代码块和同步方法有什么区别
2020-11-03 22:28:39同步代码块和同步方法有什么区别 相同点: 同步方法就是在方法前加关键字 synchronized,然后被同步的方法一次只 能有一个线程进入,其他线程等待。而同步代码块则是在方法内部使用大括 号使得一个代码块得到同步... -
同步方法和同步代码块的区别
2017-10-12 18:25:11转自:牛客网 1.同步方法使用synchronized修饰方法,在调用该方法前,需要获得内置锁(java每个...2.同步代码块使用synchronized(object){}进行修饰,在调用该代码块时,需要获得内置锁,否则就处于阻塞状态 -
JAVA线程同步方法和同步代码块
2018-08-08 16:35:58JAVA 线程同步方法和同步代码块 线程安全和非线程安全 脏读 非线程安全:多个线程对同一个对象的中的实例变量进行并发访问,产生后果就是脏读,也就是获取的数据被更改。 非线程安全问题存在与“实例变量”中,... -
同步代码块和同步方法有什么区别?
2019-11-16 11:27:11同步代码块则是在方法内部使用 synchronized 加锁对象相同的话,同步方法锁的范围大于等于同步方法块。一般加锁范围越大,性能越差 同步方法如果是 static 方法,等同于同步方法块加锁在该 Class 对象上 【Java... -
同步(同步代码块synchronized(this) 同步方法 、全局锁、同步处理方法对比)
2018-11-13 07:28:31同步代码块指同一时刻只有一个线程进入同步代码块,但是多个线程可以进入方法。 ////同步代码块 class MythreadB implements Runnable { private Integer tickets = 10 ; public void run ( ... -
浅谈同步监视器之同步代码块、同步方法
2020-08-29 14:52:32下面小编就为大家带来一篇浅谈同步监视器之同步代码块、同步方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧 -
同步方法与同步代码块的效率比较
2020-01-06 16:02:44书中提到了可以用同步代码块取代对整个方法的同步,仅对方法中操作共享变量的代码加同步锁,这样就能使没有获取到锁的线程能执行同步代码块之前的代码,进而提高程序性能。 1 代码介绍 这里采用一个因式分解的例子... -
线程中同步方法和同步代码块的区别
2019-03-27 14:11:201. 为什么要使用同步: java允许多线程并发控制,当多个线程同时操作一个可共享的资源变量时(如数据的增删改查), 将会导致数据不准确,相互之间产生冲突,因此加入同步锁以避免在该线程没有完成操作之前,被其他... -
Synchronized修饰方法和同步代码块的区别
2020-04-12 18:16:09Synchronized修饰方法和同步代码块的区别 Synchronized修饰方法的底层实现原理 Synchronized修饰同步代码块底层实现原理 代码验证 synchronized用法我们知道可以修饰实例方法,也可以修饰静态方法,还可以使用同步... -
Java中多线程、多线程的实现方式、同步代码块的方式
2020-04-30 15:13:28Java中多线程、多线程的实现方式、同步代码块的方式 -
wait、notify为什么要放在同步代码块中
2019-09-19 22:22:43暂时先把对象锁给让出来,给其它持有该锁的对象用,其它对象用完后再告知(notify)等待的那个对象可以继续执行了,因此,只有在synchronized块中才有意义(否则,如果大家并不遵循同步机制,那还等谁呢?... -
同步方法和同步代码块区别是什么
2020-02-13 16:49:40同步代码块可以选择以什么来加锁,比同步方法要更细颗粒度,我们可以选择只同步会发生同步问题的部分代码而不是整个方法; 同步方法使用关键字 synchronized修饰方法,而同步代码块主要是修饰需要进行同步的代码,用... -
同步代码块、同步方法、锁总结
2017-06-07 22:34:51同步代码块 1.为了解决并发操作可能造成的异常,java的多线程支持引入了同步监视器来解决这个问题,使用同步监视器的通用方法就是同步代码块,其语法如下: synchronized(obj){ //同步代码块 } 其中obj就是同步... -
JAVA 同步方法和同步代码块的区别是什么?
2019-06-04 12:04:33同步代码块可以选择以什么来加锁,比同步方法要更细颗粒度,我们可以选择只同步会发生同步问题的部分代码而不是整个方法; 同步方法使用关键字 synchronized修饰方法,而同步代码块主要是修饰需要进行同步的代码,用... -
java 多线程synchronized锁同步方法,同步代码块
2018-11-25 18:40:48同步和异步 我们知道多个线程共享堆内存,当两个或者多个线程调用同一个对象的方法操作对象成员时,因为cpu轮流执行线程,线程A刚开始操作对象方法,修改了数据,轮到线程B运行,线程B也操作对象方法,修改数据,可能又轮到... -
同步方法和同步代码块的使用和区别
2018-11-22 16:19:39同步方法的使用:在方法上加synchronized public synchronized void execute() { for(int i = 0; i < 20; i++) { try { Thread.sleep((long)(Math.random() * 1000)); } ... -
【多线程】synchronized同步代码块
2018-01-23 12:31:01使用synchronized声明的方法在 某些情况下是有弊端的,比如A线程调用同步的方法执行一个长时间的任务,那么B线程就必须等待比较长的时间才能执行,这种情况可以使用synchronized代码块去优化代码执行时间,也就是... -
Java中的同步代码块、同步方法、同步锁
2018-08-13 01:40:01多线程容易出现问题的原因 当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行了一部分,还没有执行完,另一个线程参与进来执行。...同步代码块 synchronized(obj) { //需要被同步的... -
java同步方法和同步代码块
2017-01-18 14:45:38一、当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。