这个问题是完全理论化的,对不起,但这次我无法回避.我正在学习ReentrantLock并阅读这篇文章:
但请注意,锁的公平性并不能保证线程调度的公平性.
这是什么意思?我怎么能想象这个?
我们假设现在没有人持有锁:
t1线程(谁不是最长的等待线程)t1 试图获得锁t1因为t1不是最长的等待线程t1 去睡觉Java是这样工作的吗?在一个非常不成功的情况下,这将意味着大量的上下文切换(导致吞吐量低,这在文档中写下来).
我想创建公平锁定,以便每个线程一个接一个地被锁定,而不管优先级如何.
import java.util.concurrent.locks.ReentrantLock;
public class StarvationRunnable implements Runnable {
private ReentrantLock lock = new ReentrantLock(true);
public void doLongTask() {
lock.lock();
// to imitate long running task in critical section
for (int i = 0; i < 1000000000; i++)
;
System.out.println(Thread.currentThread().getName() + " is running with priority "
+ Thread.currentThread().getPriority() + " !");
lock.unlock();
}
@Override
public void run() {
for (;;) {
doLongTask();
}
}
public static void main(String[] args) {
StarvationRunnable runnable = new StarvationRunnable();
for (int i = …Run Code Online (Sandbox Code Playgroud) 在 ReentrantLock 和 StampedLock 之间进行选择的用例应该是什么?例如,如果我有 10 个读者和 10 个写者,应该选择哪种锁?如果我有 20 位读者和 1 位作者,该选择哪一个?
我创建了 1000 个线程来递增,1000 个线程来递减,1000 个线程来读取值。
每个增量线程,值增加25000倍。
每个递减线程,值减少25000倍。
每个读取线程读取该值 50000 次。
所以总的来说,读操作是占主导地位的。
读取值时放置 ReadLock
WriteLock 用于递增和递减值的方法。
观察结果:ReentrantReadWriteLock 大约需要 13000 ms Lock 大约需要 3000 ms。预期:ReentrantReadWriteLock 提供比 ReentrantLock 更快的性能。
顺便说一句:我个人认为使用 getCounter 方法时不需要锁定/同步(只需读取值)
import java.util.ArrayList;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class Main {
public static void main(String[] args) throws InterruptedException {
ArrayList<Thread> reads = new ArrayList<>();
ArrayList<Thread> increments = new ArrayList<>();
ArrayList<Thread> decrements = new ArrayList<>();
Resources resources = new Resources();
long start = System.currentTimeMillis();
for (int i = 0; i < 1000; i++) …Run Code Online (Sandbox Code Playgroud) 我正在阅读有关条件的信息java.util.concurrent.locks.Condition.
条件因素将对象监视器方法(wait,notify和notifyAll)>分解为不同的对象,以通过将它们与使用任意的Lock实现相结合来实现每个对象具有多个等待集的效果.
有人可以解释一下吗?
这比普通同步块或方法有什么好处?
我正在编写一个程序,必须以两种方式修改List.尽管此实现工作正常,但它无法让第二个线程获得锁定:
Node head = new Node(new Object(), null);
public static ReentrantLock lock = new ReentrantLock();
...
boolean add(Object o){
lock.lock();
Node current = head;
Node previous = head.next;
if(head.next==null){
head.addNext(new Node(o,null));
return true;
}
while(!(current.next == null)){
current=current.next;
previous=previous.next;
}
current.addNext(new Node(o,null));
lock.unlock();
return true;
}
Run Code Online (Sandbox Code Playgroud)
也许有人知道为什么会这样?
我无法弄清楚为什么代码不能正常工作.问题是ReentrantLock没有锁定ThreadClass.run()中的方法调用
假设哪些方法在ThreadClass中被锁定的资源类
public class ResourceClass {
private int i;
public void setIncrement() {
i++;
}
public int getIncrement() {
return i;
}
}
Run Code Online (Sandbox Code Playgroud)
线程类
public class ThreadClass implements Runnable {
private ResourceClass resource;
private ReentrantLock reentrantLock = new ReentrantLock();
ThreadClass(ResourceClass r) {
resource = r;
}
public void run() {
reentrantLock.lock();
try {
resource.setIncrement();
System.out.println(resource.getIncrement());
} finally {
reentrantLock.unlock();
}
}
}
Run Code Online (Sandbox Code Playgroud)
主级
public class MainClass {
public static void main(String[] args) {
ResourceClass resource = new ResourceClass();
Thread thread …Run Code Online (Sandbox Code Playgroud) 众所周知,HotSpot VM 有偏向锁、自旋锁、轻量级锁、重量级锁等等,而 ReentrantLock 是通过 AbstractQueuedSynchronizer 实现的?AQS??那么 ReentrantLock 是 JVM 中的轻量级锁吗?
我需要像这样的线程安全的arraylist.
public class BookingList {
private List<Booking> bookings;
public BookingList() {
bookings = Collections.synchronizedList(new ArrayList<Booking>());
}
@Override
public void addBooking(Booking booking)
{
synchronized (bookings) {
bookings.add(booking);
}
}
@Override
public void removeBooking(Booking booking)
{
synchronized (bookings) {
bookings.remove(booking);
}
}
}
Run Code Online (Sandbox Code Playgroud)
根据java doc,当使用Collections.synchronizedList时,需要同步对列表的每次访问.我不确定我的同步块是否会这样做?
我使用的synchronized块是否相当于
...
public synchronized void addBooking(Booking booking) {
bookings.add(booking);
}
Run Code Online (Sandbox Code Playgroud)我应该像这样使用ReentrantLock吗?
private Lock lock = new ReentrantLock();
public void addBooking(Booking booking) {
try {
lock.lock;
bookings.add(booking);
} finally {
lock.release();
}
}
Run Code Online (Sandbox Code Playgroud)我搜索了很多但是与'ReentrantLock'和正常'synchronized'的过程相混淆.
例如(1):
Object obj = new Object();
synchronized(obj){
//lock is guaranteed to be acquired
}
Run Code Online (Sandbox Code Playgroud)
例子(2)
Lock lock = new ReentrantLock();
lock.lock(); //problem here
try{
//dostuff
}
finally{
lock.unlock();
}
Run Code Online (Sandbox Code Playgroud)
我的问题是:
在示例1中:保证使用synchronized关键字获取对象的锁定.
但
在示例2中:是否保证使用lock.lock()方法获取锁?或者线程会进入下一行执行?没有获得锁.
我对此表示怀疑,因为使用线程已经多次为我带来意想不到的结果.
问题出在哪儿?ReentrantLock未显示预期结果.两个线程正在执行相同的时间而不是等待一个线程.
class MyThread2 extends Thread{
String name;
ReentrantLock reentrantLock = new ReentrantLock();
MyThread2(String name){
this.name = name;
}
public void run(){
do {
try {
if (reentrantLock.tryLock(20,TimeUnit.MILLISECONDS)){
System.out.println("executing : "+ name);
Thread.sleep(500);
reentrantLock.unlock();
break;
}else {
System.out.println("waiting "+ name);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}while (true);
}
}
public class LockDemo2{
public static void main(String[] args) {
new MyThread2("Thread - 1").start();
new MyThread2("Thread - 2").start();
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
executing : Thread - 1
executing : …Run Code Online (Sandbox Code Playgroud) java concurrency multithreading java.util.concurrent reentrantlock