介紹
ReentrantLock是互斥排他鎖佑淀,同一時間只能有一個線程在執(zhí)行任務,ReentrantLock支持鎖的重入功能捧颅,雖然保證了線程的安全性亮蒋,但是效率不高贮尖,實際上應該是寫操作互斥,讀操作共享任连。而jdk提供了讀寫鎖ReentrantReadWriteLock裁着。
讀讀共享
public class MyTask {
private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
public void read() {
try {
lock.readLock().lock();
System.out.println(Thread.currentThread().getName() + " start");
Thread.sleep(10000);
System.out.println(Thread.currentThread().getName() + " end");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.readLock().unlock();
}
}
}
public class ReadReadTest {
public static void main(String[] args) {
final MyTask myTask = new MyTask();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
myTask.read();
}
});
t1.setName("t1");
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
myTask.read();
}
});
t2.setName("t2");
t1.start();
t2.start();
}
}
結果:
t2 start
t1 start
t1 end
t2 end
寫寫互斥
public class MyTask {
private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
public void write() {
try {
lock.writeLock().lock();
System.out.println(Thread.currentThread().getName() + " start");
Thread.sleep(10000);
System.out.println(Thread.currentThread().getName() + " end");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.writeLock().unlock();
}
}
}
public class ReadReadTest {
public static void main(String[] args) {
final MyTask myTask = new MyTask();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
myTask.write();
}
});
t1.setName("t1");
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
myTask.write();
}
});
t2.setName("t2");
t1.start();
t2.start();
}
}
結果:
t1 start
t1 end
t2 start
t2 end
讀寫互斥
public class MyTask {
private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
public void read() {
try {
lock.readLock().lock();
System.out.println(Thread.currentThread().getName() + " start");
Thread.sleep(10000);
System.out.println(Thread.currentThread().getName() + " end");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.readLock().unlock();
}
}
public void write() {
try {
lock.writeLock().lock();
System.out.println(Thread.currentThread().getName() + " start");
Thread.sleep(10000);
System.out.println(Thread.currentThread().getName() + " end");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.writeLock().unlock();
}
}
}
public class ReadReadTest {
public static void main(String[] args) {
final MyTask myTask = new MyTask();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
myTask.read();
}
});
t1.setName("t1");
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
myTask.write();
}
});
t2.setName("t2");
t1.start();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
t2.start();
}
}
結果:
t1 start
t1 end
t2 start
t2 end
寫讀互斥
public class ReadReadTest {
public static void main(String[] args) {
final MyTask myTask = new MyTask();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
myTask.write();
}
});
t1.setName("t1");
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
myTask.read();
}
});
t2.setName("t2");
t1.start();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
t2.start();
}
}
結果:
t1 start
t1 end
t2 start
t2 end
總結
讀操作的鎖叫共享鎖拱她,寫操作的鎖叫排他鎖二驰。就是遇見寫鎖就需互斥。那么以此可得出讀讀共享秉沼,寫寫互斥桶雀,讀寫互斥矿酵,寫讀互斥。