当我们调用lock.lock()或尝试输入synchronized块时,如果其他某个线程已经获得了该锁,则我们的线程将阻塞。 现在我的问题是,当我们查看lock.lock()的实现时,它会将获取锁委托给AQS,而AQS实际将当前线程驻留在该线程中(因此调度程序无法对其进行进一步调度)。

synchronized阻塞是否也是如此?

我什至认为我的线程状态也不同。 例如,如果我的线程在synchronized块上被阻塞,则它将是BLOCKING,而如果我调用了

lock.lock(),则为WAITING。 我对吗?

我关心的是以下两种锁定策略在Thread.status方面与通过停车而不是忙于等待来提高性能之间的区别

ReentrantLock.lock();

synchronize { /*some code */ }

抱歉,我从自动翻译器回复。 我认为您应该附加示例代码,这将帮助我们帮助您分析问题。 一般在使用同步时,可以不必锁定。 锁 ()。 一般来说,足够同步。

调用lock或lockInterruptibly会将线程置于WAITING状态:

Thread state for a waiting thread. A thread is in the waiting state due to calling one of the following methods:

Object.wait with no timeout

Thread.join with no timeout

LockSupport.park

以下代码启动四个线程,前两个(A,B)运行相同的代码,并通过lock方法锁定某些监视器。 另外两个(C,D)也运行相同的代码,但是它们通过lockInterruptibly方法锁定了另一个监视器:

public static synchronized void dumpThreadState(List threads) {

System.out.println("thread state dump start");

for (Thread t: threads) {

System.out.println(t.getName()+""+t.getState());

}

System.out.println("thread state dump end\

");

}

public static void main(String[] args) throws InterruptedException {

final Lock lock = new ReentrantLock();

final Lock anotherLock = new ReentrantLock();

List threads = new LinkedList();

Runnable first = new Runnable() {

@Override

public void run() {

try {

lock.lock();

}

catch (Exception ex) {

System.out.println(Thread.currentThread().getName()+" processing exception"+ex.getClass().getSimpleName());

}

while (true);

}

} ;

Runnable second = new Runnable() {

@Override

public void run() {

try {

anotherLock.lockInterruptibly();

}

catch (InterruptedException ex) {

System.out.println(Thread.currentThread().getName()+" was interrupted");

}

while (true);

}

};

threads.add(new Thread(first,"A"));

threads.add(new Thread(first,"B"));

threads.add(new Thread(second,"C"));

threads.add(new Thread(second,"D"));

dumpThreadState(threads);

for (Thread t: threads) {

t.start();

}

Thread.currentThread().sleep(100);

dumpThreadState(threads);

System.out.println("interrupting" + threads.get(1).getName());

threads.get(1).interrupt();

dumpThreadState(threads);

System.out.println("interrupting" + threads.get(3).getName());

threads.get(3).interrupt();

Thread.currentThread().sleep(100);

dumpThreadState(threads);

for (Thread t: threads) {

t.join();

}

}

它输出:

thread state dump start

A NEW

B NEW

C NEW

D NEW

thread state dump end

thread state dump start

A RUNNABLE

B WAITING

C RUNNABLE

D WAITING

thread state dump end

interrupting B

thread state dump start

A RUNNABLE

B WAITING

C RUNNABLE

D WAITING

thread state dump end

interrupting D

D was interrupted

thread state dump start

A RUNNABLE

B WAITING

C RUNNABLE

D RUNNABLE

thread state dump end

可以看出,通过lock方法锁定的线程不能被中断,而通过lockInterruptibly锁定的线程可以被中断。

在另一个示例中,启动了三个线程,前两个(A,B)运行相同的代码,并通过synchronized块锁定在同一监视器上。 第三个线程锁定在另一个监视器上,但通过wait方法等待:

public static void main(String[] args) throws InterruptedException {

final Object lock = new Object();

final Object anotherLock = new Object();

List threads = new LinkedList();

Runnable first = new Runnable() {

@Override

public void run() {

synchronized(lock) {

while (true);

}

}

} ;

Runnable second = new Runnable() {

@Override

public void run() {

synchronized(anotherLock) {

try {

anotherLock.wait();

}

catch (InterruptedException ex) {

ex.printStackTrace();

}

}

}

};

threads.add(new Thread(first,"A"));

threads.add(new Thread(first,"B"));

threads.add(new Thread(second,"C"));

dumpThreadState(threads);

for (Thread t: threads) {

t.start();

}

Thread.currentThread().sleep(100);

dumpThreadState(threads);

for (Thread t: threads) {

t.join();

}

}

它输出:

thread state dump start

A NEW

B NEW

C NEW

thread state dump end

thread state dump start

A RUNNABLE

B BLOCKED

C WAITING

thread state dump end

线程C以WAITING状态结束,而线程B以BLOCKING状态结束:

Thread state for a thread blocked waiting for a monitor lock. A thread in the blocked state is waiting for a monitor lock to enter a synchronized block/method or reenter a synchronized block/method after calling Object.wait.

编辑:

这是一个非常好的线程状态的UML图。

阻止-在资源上被阻止,无法被中断

等待-在资源上被阻止,但可以被中断,通知或取消停放。

如您所见,Waiting更好地控制了另一个处理程序。例如如果两个线程死锁,则可以通过中断来中断lock()。使用同步的两个线程时,您将陷入困境。

同步vs锁定的行为非常相似,确切的细节在主要版本之间有所不同。

我的建议是使用

同步以获取需要线程安全但锁争用非常低的简单代码。

在已确定有锁争用的地方使用Lock,或者需要其他功能,例如tryLock。

如果你这样做

final Lock lock = new ReentrantLock();

lock.lock();

Thread t = new Thread(new Runnable() {

@Override

public void run() {

try {

lock.lockInterruptibly();

} catch (InterruptedException e) {

e.printStackTrace();

}

}

});

t.start();

Thread.sleep(100);

System.out.println(t +" is" + t.getState());

lock.unlock();

版画

Thread[Thread-0,5,main] is WAITING

Thread.State状态

等待线程的线程状态。由于调用以下方法之一,线程处于等待状态:

Object.wait没有超时

Thread.join没有超时

LockSupport.park

处于等待状态的线程正在等待另一个线程执行特定操作。例如,一个在对象上调用Object.wait()的线程正在等待另一个线程在该对象上调用Object.notify()或Object.notifyAll()。名为Thread.join()的线程正在等待指定的线程终止。

谢谢@Peter Lawrey,当线程被lock.lock()阻塞时,线程的状态如何?

好的一点是,lock()将被阻塞,而lockInterruptably()将被等待,因为它可以被中断。

@PeterLawrey调用锁也会使线程也处于等待状态

驻留线程和同步阻塞是非常不同的。尝试输入同步块时,您将明确尝试在对象实例上获取监视器。如果无法获取监视器,则线程将进入"阻塞"状态,直到监视器可用为止。停放与Object.wait()方法更相似,因为代码知道在其他条件变为真之前它不能继续。阻止在这里是没有意义的,因为这将是徒劳的,因为我目前继续的条件是正确的。此时,我进入WAITING或TIMED_WAITING状态(取决于等待的发出方式),直到被通知(通过类似notify(),notifyAll()或unpark()的通知)为止。一旦我的条件变为真,我就进入等待状态,然后可能会尝试获取监视器并在需要时进入阻塞状态。如果我得到显示器,则进入"运行"并继续快乐地前进

因此,等待实际上就是知道我无法做某事,并在认为可以的情况下让其他线程通知我。我醒来后可能导致阻塞。阻塞只是争夺对监视器的访问,而没有其他明确的先决条件。

在Lock实例上调用lock()时,调用线程实际上处于等待状态,并且没有阻塞。这样做的好处是可以中断此等待状态,这有助于避免死锁。对于类似Lock类的东西,您可以通过tryLock(),tryLock(long,TimeUnit),lock()和lockInterruptibly()来选择所需的等待行为。您可以指定诸如要等待多长时间以及是否可以通过调用哪种方法打扰您之类的事情。使用synchronized代码,您没有此类选项。您正在阻塞,并且被阻塞阻塞,直到某个线程放弃了您想要的监视器为止,如果从未中断,您将陷入僵局。这就是为什么从Java 5和concurrent包开始,您应该避免使用synchronized关键字,而是尝试使用Lock和Condition之类的东西实现类似的语义。

谢谢@ cmbaxter,实际上我想问的是,当它调用Reentrantlock.lock()时,线程实际上进入了停车状态。 这就是为什么我的问题在ReentrantLock.lock()中被阻止的原因实际上并未被阻止

是的,如果锁当前不可用,则调用lock会将调用线程置于WAITING状态。

java 同步 lock_关于java:同步是否像Lock.lock()一样驻留并发线程?相关推荐

  1. python和java选择哪个-观点|Java 与 Python:你应该选择哪个?

    比较世界上最流行的两种编程语言,并在投票中让我们知道你喜欢哪一个. 让我们比较一下世界上两种最受欢迎.最强大的编程语言:Java 和 Python!这两种语言有巨大的社区支持和库来执行几乎任何编程任务 ...

  2. java condition_死磕 java同步系列之ReentrantLock源码解析(二)

    (手机横屏看源码更方便) 问题 (1)条件锁是什么? (2)条件锁适用于什么场景? (3)条件锁的await()是在其它线程signal()的时候唤醒的吗? 简介 条件锁,是指在获取锁之后发现当前业务 ...

  3. Java并发——线程间通信与同步技术

    传统的线程间通信与同步技术为Object上的wait().notify().notifyAll()等方法,Java在显示锁上增加了Condition对象,该对象也可以实现线程间通信与同步.本文会介绍有 ...

  4. java同步方法完成案例_Java同步代码块和同步方法原理与应用案例详解

    本文实例讲述了java同步代码块和同步方法.分享给大家供大家参考,具体如下: 一 点睛 所谓原子性WOmoad:一段代码要么执行,要么不执行,不存在执行一部分被中断的情况.言外之意是这段代码就像原子一 ...

  5. java笔记--关于线程同步(7种同步方式)

    关于线程同步(7种方式) --如果朋友您想转载本文章请注明转载地址"http://www.cnblogs.com/XHJT/p/3897440.html"谢谢-- 为何要使用同步? ...

  6. java 同步方式 lock_Java的同步锁(Lock)

    从Java 5开始,Java提供了一种功能更强大的线程同步机制一-通过 显式定义同步锁对象来实现同步,在这种机制下,同步锁由Lock对象充当.Lock提供了比synchronized方法和synchr ...

  7. java基础提升篇:synchronized同步块和volatile同步变量

    初遇 Java语言包含两种内在的同步机制:同步块(或方法)和 volatile 变量.这两种机制的提出都是为了实现代码线程的安全性.其中 Volatile 变量的同步性较差(但有时它更简单并且开销更低 ...

  8. java中同步_在Java中的方法同步和语句同步(块同步) - Break易站

    Java 多线程 线程主要通过共享对字段的访问和参考字段引用的对象进行通信.这种通信形式非常有效,但可能出现两种错误:线程干扰和内存一致性错误.需要一些同步构造来防止这些错误.以下示例显示了我们需要同 ...

  9. 从操作系统的PV操作理解JAVA的synchronized同步方法,同步代码块实现,及比较

    也有利于理解操作系统的同步 知识果然是息息相关的 JAVA同样离不开操作系统的原理,不过他体现在虚拟机JVM中 synchronized关键字是同步关键字 首先我们知道在操作系统里 PV两者操作信息量 ...

最新文章

  1. 报名 | 2019清华大数据系统软件峰会
  2. 支付宝接口调用问题快速通道
  3. 关键词热度分析工具_亚马逊卖家: 产品关键词挖掘分析必备工具!
  4. Java后端向前端传递数据,挥泪整理面经
  5. 【杂谈】三人行必有AI,你会在其一吗?
  6. boost::program_options模块实现处理选项组的测试程序
  7. [渝粤教育] 江西科技师范大学 旅行社经营管理 参考 资料
  8. 虚函数,虚基类 与纯虚函数 二
  9. 【Elasticsearch】Elasticsearch日志场景最佳实践
  10. Xshell 常见问题及相关配置
  11. 计算机英语词典 txt,9种Txt格式朗文英语词典免费分享
  12. 如何将现有Apple ID 更改为美区
  13. KendoGrid的使用
  14. 英语口语收集(二十六)
  15. 体绘制加速技术之数据异步传输
  16. WordPress免认证微信关注登陆插件
  17. Xubuntu22.04设置全局代理(一百五十六)
  18. 安静:内向性格的竞争力 苏珊·凯恩
  19. 淘宝/天猫/京东/抖音和聚划算百亿补贴、预售定金直链/BP链接制作生成教程
  20. 拍卖小程序直播功能扩展之翻转摄像头、美颜

热门文章

  1. android 8三星note8,信息太多很烦琐?告诉你三星Note8有妙招
  2. 击鼓传花c语言编程题,c语言-第5章 循环程序设计.ppt
  3. 打印狗的健康值Java_嵌入式狗的JAVA之路 HTML 补课
  4. mysql 64位 安装1045_MySql 安装时的1045错误
  5. node将图片转换成html文件,node+puppeteer将整个网页html转换为图片并保存【滚动截屏】...
  6. linux怎么启动端口服务,Linux 根据端口快速停止服务并启动的办法
  7. mysql重复记录大于十的数据库_面试官:在使用mysql数据库时,遇到重复数据怎么处理?...
  8. android+fastboot+命令,Android手机fastboot刷机命令
  9. 16字节 oracle md5,Oracle中的MD5加密
  10. AOE网的关键路径的计算