Tag: 锁定

使用Timeout避免Javamultithreading中的死锁

避免Javamultithreading中死锁情况的策略之一是使用超时。 假设,一个线程已获得对一个资源的锁定,现在正在等待另一个资源上的锁定。 经过一段时间后,如果无法获取资源2的锁定,则应该停止等待资源2上的锁定。 它也应该释放对resource1的锁定。 因此将避免死锁。 但是如何在Java中实现它? 如何明确“释放”锁定? 如何定义等待锁的超时。 什么是精确的java命令和语法。 请问任何问候世界的例子吗?

为什么Java和C#会为每个对象添加内部锁?

使每个对象可锁定看起来像一个设计错误: 您为每个创建的对象添加了额外的成本,即使您实际上只在一小部分对象中使用它。 锁定用法变得隐含,具有lockMap.get(key).lock()比任意对象上的同步更具可读性,例如, synchronize (key) {…} 。 同步方法可能会导致用户使用synchronized方法锁定对象时出现细微错误 您可以确定在将对象传递给第3个parting API时,它的锁定未被使用。 例如 class Syncer { synchronized void foo(){} } … Syncer s = new Syncer(); synchronize(s) { … } // in another thread s.foo() // oops, waiting for previous section, deadlocks potential 更不用说每个对象的命名空间压缩(在C#中至少方法是静态的,在Java同步原语中必须使用await ,而不是在Object重载wait …) 但是我确信这个设计有一些原因。 内在锁的好处是什么?

将一个线程置于hibernate状态,直到另一个线程中的条件得到解决

以下是完成(我认为)同样事情的两个代码块。 我基本上是在尝试学习如何使用Java 1.5的并发来摆脱Thread.sleep(long)。 第一个示例使用ReentrantLock,第二个示例使用CountDownLatch。 我想要做的就是让一个线程进入hibernate状态,直到另一个线程中的条件得到解决。 ReentrantLock提供了一个布尔锁,用于决定是否唤醒另一个线程,然后我使用条件和等待/信号来hibernate另一个线程。 据我所知,我需要使用锁的唯一原因是,如果多个线程需要对boolean的写访问权。 CountDownLatch似乎提供与ReentrantLock相同的function,但没有(不必要的?)锁。 然而,感觉就像我通过初始化它只需要一次倒计时来劫持它的预期用途。 我认为它应该在多个线程要处理同一个任务时使用,而不是在多个线程在等待一个任务时使用。 所以,问题: 我在ReentrantLock代码中使用锁定“正确的东西”吗? 如果我只在一个线程中写入布尔值,那么锁是否必要? 只要我在唤醒任何其他线程之前重置布尔值我就不会导致问题,我可以吗? 是否有一个类似于CountDownLatch的类,我可以使用它来避免锁定(假设我应该在这个实例中避免它们),这更适合这个任务? 有没有其他方法来改进我应该注意的代码? 例1: import java.util.concurrent.locks.*; public class ReentrantLockExample extends Thread { //boolean – Is the service down? boolean serviceDown; // I am using this lock to synchronize access to sDown Lock serviceLock; // and this condition to sleep any threads waiting […]

在java中有偏见的锁定

我继续阅读有关如何使用标志-XX:+ UseBiasedLocking进行偏置锁定可以提高无竞争同步的性能。 我无法找到它的作用以及它如何改善性能。 任何人都可以解释我究竟是什么,或者可能指向我解释一些链接/资源?

为什么在CopyOnWriteArrayList中需要setArray()方法调用

在CopyOnWriteArrayList.java中,在方法集(int index,E element)下面 public E set(int index, E element) { final ReentrantLock lock = this.lock; lock.lock(); try { Object[] elements = getArray(); Object oldValue = elements[index]; if (oldValue != element) { int len = elements.length; Object[] newElements = Arrays.copyOf(elements, len); newElements[index] = element; setArray(newElements); } else { // Not quite a no-op; ensures volatile write […]

在Java中,AtomicInteger compareAndSet()与synchronized关键字的性能如何?

我正在实现请求实例的FIFO队列(预分配的请求对象以提高速度),并在add方法上使用“synchronized”关键字开始。 该方法非常短(检查固定大小缓冲区中的空间,然后向数组添加值)。 使用visualVM看起来线程比我喜欢的更频繁地阻塞(“监视器”是精确的)。 所以我将代码转换为使用AtomicInteger值,例如跟踪当前大小,然后在while循环中使用compareAndSet()(因为AtomicInteger在内部为incrementAndGet()等方法执行)。 现在代码看起来要长一些。 我想知道的是使用synchronized和更短代码的性能开销与没有synchronized关键字的更长代码相比(因此永远不应该阻塞锁)。 这是使用synchronized关键字的旧get方法: public synchronized Request get() { if (head == tail) { return null; } Request r = requests[head]; head = (head + 1) % requests.length; return r; } 这是没有synchronized关键字的新get方法: public Request get() { while (true) { int current = size.get(); if (current <= 0) { return null; } if […]

为什么等待条件释放锁定但信号没有?

我编写下面的代码来测试线程在等待Condition对象时何时处于唤醒Condition 。 但是我发现在调用signal()之后我必须解锁。 此方法不会释放锁定,而await()将释放此锁定。 这是来自条件#等待 与此条件关联的锁被primefaces释放 ,并且当前线程因线程调度而被禁用,并处于hibernate状态,直到发生以下四种情况之一: 这是来自Conditon#signal 唤醒一个等待线程。 如果有任何线程在这种情况下等待,则选择一个线程进行唤醒。 然后该线程必须在从await返回之前重新获取锁。 但在我的代码中,这是不正确的,直到我们解锁。 为什么这样设计? 因为在我看来,当我们决定向其他人发出信号时,我们不应再持有锁,我错了吗? 既然我们可以在调用signal和unlock之间做很多事情,比如说我睡了10秒,那么java信号的另一个线程到底是什么时候? 还有另一个背景线程在我们发signal和unlock之间工作吗? public class WorkerThread extends Thread{ @Override public void run() { Monitor.lock.lock(); while (!Monitor.isConditionTrue){ try { Monitor.condition.await(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(“THREAD ID “+this.getId()+”——-working ——–“); System.out.println(“——singnall——–“); Monitor.isConditionTrue=true; Monitor.condition.signal(); try { Thread.sleep(3000);//here, the thread is sleeping while […]

Java阻塞问题:为什么JVM会在许多不同的类/方法中阻塞线程?

更新:这看起来像一个内存问题。 一个3.8 Gb的Hprof文件表明当发生“阻塞”时,JVM正在转储它的堆。 我们的运营团队发现该站点没有响应,进行了堆栈跟踪,然后关闭了该实例。 我相信他们在堆转储完成之前关闭了网站。 日志没有错误/exception/问题证据 – 可能是因为JVM在生成错误消息之前被杀死了。 原始问题我们有一个最近的情况,应用程序出现 – 最终用户 – 挂起。 我们在应用程序重启之前得到了一个堆栈跟踪,我发现了一些令人惊讶的结果:527个线程,463个线程状态为BLOCKED。 在过去过去被阻塞的线程通常有这个问题:1)一些明显的瓶颈:例如一些数据库记录锁定或文件系统锁定问题导致其他线程等待。 2)所有被阻塞的线程将阻塞相同的类/方法(例如jdbc或文件系统clases) 不寻常的数据在这种情况下,除了应用程序类(包括jdbc和lucene调用)之外,我还看到了各种类/方法被阻止,包括jvm内部类,jboss类,log4j等 问题是什么会导致JVM阻止log4j.Hierarchy.getLogger,java.lang.reflect.Constructor.newInstance? 显然有些资源“稀缺”,但哪些资源? 谢谢 将 堆栈跟踪摘录 http-0.0.0.0-80-417″ daemon prio=6 tid=0x000000000f6f1800 nid=0x1a00 waiting for monitor entry [0x000000002dd5d000] java.lang.Thread.State: BLOCKED (on object monitor) at sun.reflect.GeneratedConstructorAccessor68.newInstance(Unknown Source) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27) at java.lang.reflect.Constructor.newInstance(Constructor.java:513) at java.lang.Class.newInstance0(Class.java:355) at java.lang.Class.newInstance(Class.java:308) at org.jboss.ejb.Container.createBeanClassInstance(Container.java:630) http-0.0.0.0-80-451″ daemon prio=6 tid=0x000000000f184800 nid=0x14d4 […]

通过具体(Java)示例进行乐观锁定

我早上花了很多时间阅读谷歌在乐观锁定方面所做的所有热门文章,而对于我的生活,我仍然没有真正理解。 我理解乐观锁定涉及添加用于跟踪记录的“版本”的列,并且该列可以是时间戳,计数器或任何其他版本跟踪构造。 但我仍然不明白如何确保WRITE完整性(意味着如果多个进程同时更新同一个实体,那么之后,实体正确地反映了它应该处于的真实状态)。 有人可以提供一个具体的,易于理解的例子,说明如何在Java中使用乐观锁定(可能是MySQL DB)。 假设我们有一个Person实体: public class Person { private String firstName; private String lastName; private int age; private Color favoriteColor; } 并且Person实例被持久化到一个people MySQL表: CREATE TABLE people ( person_id PRIMARY KEY AUTO_INCREMENT, first_name VARCHAR(100) NOT NULL, last_name VARCHAR(100) NOT NULL, # } I realize these column defs are not valid but this is just […]

锁定特定对象的Java线程

我有一个Web应用程序,我正在使用Oracle数据库,我有一个基本上像这样的方法: public static void saveSomethingImportantToDataBase(Object theObjectIwantToSave) { if (!methodThatChecksThatObjectAlreadyExists) { storemyObject() //pseudo code } // Have to do a lot other saving stuff, because it either saves everything or nothing commit() // pseudo code to actually commit all my changes to the database. } 现在没有任何类型的同步,所以n个线程当然可以自由地访问这个方法,当2个线程进入这个方法同时检查时会出现问题,当然还没有任何东西,然后他们都可以提交事务,创建重复的对象。 我不想在我的数据库中使用唯一的密钥标识符来解决这个问题,因为我认为我不应该捕获那个SQLException 。 我也无法在提交之前检查,因为有几个检查不仅1 ,这将花费相当多的时间。 我对锁和线程的体验是有限的,但我的想法基本上是将这个代码锁定在它接收的对象上。 我不知道例如说我收到一个整数对象,并且我用值1锁定我的整数,这只会阻止具有值为1的另一个Integer的线程进入,而所有其他具有value != 1线程都可以自由进入?,这是怎么回事? 此外,如果这是它的工作原理,锁对象如何比较? 它是如何确定它们实际上是同一个对象的? […]