版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_33248299/article/details/78778263
Lock比传统线程模型中的synchronized方式更加面向对象,与生活中的锁类似,锁本身也应该是一个对象。两个线程执行的代码片段要实现同步互斥的效果,它们必须要同一个Lock对象。锁是上在代表要操作的资源的类的内部方法中,而不是变成代码中!
读写锁:分为读锁和写锁,多个读锁不互斥,读锁与写锁互斥,写锁与写锁互斥,这是由jvm自己控制的,你只要上好相应的锁即可。如果你的低吗只读数据,可以很多人同时读,但不能同时写,那就上读锁;如果你的代码修改数据,只能有一个人再写,且不能同时读取,那就上写锁。总之,读的时候上读锁,写的时候上写锁!
Lock在java,util.concurrent.locks包下
开两个线程打印名字,用synchronized实现效果如下
public class LockTest {
public static void main(String[] args) {
new LockTest().init();
}
public void init() {
final Output output = new Output();
new Thread(new Runnable() {
@Override
public void run() {
while(true) {
output.getName("zhouyuan");
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
while(true) {
output.getName("muchen");
}
}
}).start();
}
static class Output{
public void getName(String name) {
synchronized (Output.class) {
for(int i=0;i<name.length();i++) {
System.out.print(name.charAt(i));
}
System.out.println();
}
}
}
}
- 把以上改成Lock实现
public class LockTest {
public static void main(String[] args) {
new LockTest().init();
}
public void init() {
final Output output = new Output();
new Thread(new Runnable() {
@Override
public void run() {
while(true) {
output.getName("zhouyuan");
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
while(true) {
output.getName("muchen");
}
}
}).start();
}
static class Output{
Lock lock = new ReentrantLock();
public void getName(String name) {
try {
for(int i=0;i<name.length();i++) {
System.out.print(name.charAt(i));
}
System.out.println();
}
}
}
- 虽然上面的代码没有什么大的问题,不过还是存在一个问题,如果在for循环内抛出了异常,那么这个getName方法就直接跳出了,就不会运行解锁,所以我们最好加上finally,如下
public class LockTest {
public static void main(String[] args) {
new LockTest().init();
}
public void init() {
final Output output = new Output();
new Thread(new Runnable() {
@Override
public void run() {
while(true) {
output.getName("zhouyuan");
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
while(true) {
output.getName("muchen");
}
}
}).start();
}
static class Output{
Lock lock = new ReentrantLock();
public void getName(String name) {
lock.lock();
try {
for(int i=0;i<name.length();i++) {
System.out.print(name.charAt(i));
}
System.out.println();
}finally {//如果for内抛异常,不加这个这个方法就直接跳出了
lock.unlock();
}
}
}
}