玩转java多线程 之多线程基础 Lock锁实战练习
·
从JDK5.0开始,java提供了更强大的线程同步机制,通过显式定义同步锁对象来实现同步,同步锁用Lock对象充当。
java.util.concurrent.locks Lock接口是控制多个线程对共享资源进行访问的工具,锁提供了对共享资源的独占访问,每次只能有一个线程对Lock对象加锁,线程开始访问共享资源之前应该先获得Lock对象。
ReentrantLock类实现了Lock, 它拥有与synchronized相同的并发性和内存语义,在实现线程安全的控制中,比较常用的是ReentrantLock,可以显式加锁,释放锁。
实战一下:
package duoxiancheng;
//测试lock锁
public class TestLock {
public static void main(String[] args) {
TestLock2 testLock2 = new TestLock2();
new Thread(testLock2).start();
new Thread(testLock2).start();
new Thread(testLock2).start();
}
}
class TestLock2 implements Runnable {
int ticketNum = 10;
@Override
public void run() {
while(true) {
if(ticketNum > 0) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(ticketNum--);
} else {
break;
}
}
}
}
不加锁,是不安全的:

使用锁之后:
package duoxiancheng;
import java.util.concurrent.locks.ReentrantLock;
//测试lock锁
public class TestLock {
public static void main(String[] args) {
TestLock2 testLock2 = new TestLock2();
new Thread(testLock2).start();
new Thread(testLock2).start();
new Thread(testLock2).start();
}
}
class TestLock2 implements Runnable {
int ticketNum = 10;
//定义lock 锁
private final ReentrantLock lock = new ReentrantLock();
@Override
public void run() {
while(true) {
try {
//加锁
lock.lock();
if(ticketNum > 0) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(ticketNum--);
} else {
break;
}
} finally {
//解锁
lock.unlock();
}
}
}
}

这样就能保证是线程安全的
synchronized与lock对比:
lock是显式锁,需要手动开启或者关闭锁,synchronized是隐式锁,出了作用域自动释放
lock只有代码块锁,synchronized有代码块锁和方法锁
使用lock锁,jvm花费较少的时间来调度线程,性能更好,并且具有更好的扩展性,提供更多的子类
优先使用顺序,lock -》 同步代码块(已经进入了方法体,分配了相应的资源)-》同步方法(在方法体之外)
好了,今天先到这里
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐


所有评论(0)