永发信息网

线程锁的原理是什么

答案:1  悬赏:70  手机版
解决时间 2021-12-01 03:41
线程锁的原理是什么
最佳答案
线程锁的使用 本文内容何时该使用线程锁.
线程锁的写法.
以线程锁的例子来理解线程的调度。使用线程锁的场合程序中经常采用多线程处理,这可以充分利用系统资源,缩短程序响应时间,改善用户体验;如果程序中只使用单线程,那么程序的速度和响应无疑会大打折扣。
但是,程序采用了多线程后,你就必须认真考虑线程调度的问题,如果调度不当,要么造成程序出错,要么造成荒谬的结果。一个讽刺僵化体制的笑话前苏联某官员去视察植树造林的情况,现场他看到一个人在远处挖坑,其后不远另一个人在把刚挖出的坑逐个填上,官员很费解于是询问陪同人员,当地管理人员说“负责种树的人今天病了”。
上面这个笑话如果发生在程序中就是线程调度的问题,种树这个任务有三个线程:挖坑线程,种树线程和填坑线程,后面的线程必须等前一个线程完成才能进行,而不是按时间顺序来进行,否则一旦一个线程出错就会出现上面荒谬的结果。用线程锁来处理两个线程先后执行的情况在程序中,和种树一样,很多任务也必须以确定的先后秩序执行,对于两个线程必须以先后秩序执行的情况,我们可以用线程锁来处理。
线程锁的大致思想是:如果线程A和线程B会执行实例的两个函数a和b,如果A必须在B之前运行,那么可以在B进入b函数时让B进入wait set,直到A执行完a函数再把B从wait set中激活。这样就保证了B必定在A之后运行,无论在之前它们的时间先后顺序是怎样的。线程锁的代码如右,SwingComponentLock的实例就是一个线程锁,lock函数用于锁定线程,当完成状态isCompleted为false时进入的线程会进入SwingComponentLock的实例的wait set,已完成则不会;要激活SwingComponentLock的实例的wait set中等待的线程需要执行unlock函数。public class SwingComponentLock {
// 是否初始化完毕
boolean isCompleted = false;
public synchronized void lock() {
while (!isCompleted) {
try {
wait();
} catch (Exception e) {
e.printStackTrace();
logger.error(e.getMessage());
}
}
}
public synchronized void unlock() {
isCompleted = true;
notifyAll();
}
}线程锁的使用public class TreeViewPanel extends BasePanel {
// 表空间和表树
private JTree tree; // 这个是防树还未初始化好就被刷新用的
private SwingComponentLock treeLock; protected void setupComponents() {
// 初始化锁
treeLock = new SwingComponentLock(); // 创建根节点
DefaultMutableTreeNode root = new DefaultMutableTreeNode("DB");
tree = new JTree(root); // 设置布局并装入树
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
add(new JScrollPane(tree)); // 设置树节点的图标
setupTreeNodeIcons(); // 解除对树的锁定
treeLock.unlock();
}
public synchronized void refreshTree(List schemas) {
treeLock.lock(); DefaultTreeModel model = (DefaultTreeModel) tree.getModel(); DefaultMutableTreeNode root = (DefaultMutableTreeNode) model.getRoot();
root.removeAllChildren(); for (SchemaTable schemaTable : schemas) {
DefaultMutableTreeNode schemaNode = new DefaultMutableTreeNode(
schemaTable.getSchema()); for (String table : schemaTable.getTables()) {
schemaNode.add(new DefaultMutableTreeNode(table));
} root.add(schemaNode);
} model.reload();
}讲解上页中,setupComponents函数是Swing主线程执行的,而refreshTree函数是另外的线程执行(初始化时程序开辟一个线程执行,其后执行由用户操作决定)。 refreshTree函数必须要等setupComponents函数把tree初始化完毕后才能执行,而tree初始化的时间较长,可能在初始化的过程中执行refreshTree的线程就进入了,这就会造成问题。
程序使用了一个SwingComponentLock来解决这个问题,setupComponents一开始就创建SwingComponentLock的实例treeLock,然后执行refreshTree的线程以来就会进入treeLock的wait set,变成等待状态,不会往下执行,这是不管tree是否初始化完毕都不会出错;而setupComponents执行到底部会激活treeLock的wait set中等待的线程,这时再执行refreshTree剩下的代码就不会有任何问题,因为setupComponents执行完毕tree已经初始化好了。
让线程等待和激活线程的代码都在SwingComponentLock类中,这样的封装对复用很有好处,如果其它复杂组件如table也要依此办理直接创建SwingComponentLock类的实例就可以了。如果把wait和notifyAll写在TreeViewPanel类中就不会这样方便了。总结线程锁用于必须以固定顺序执行的多个线程的调度。
线程锁的思想是先锁定后序线程,然后让线序线程完成任务再解除对后序线程的锁定。
线程锁的写法和使用一定要理解记忆下来。
我要举报
如以上问答信息为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
智能手机充电usb插口是四根线,它的黑红绿白
德州临邑到德平公交车次的路线及乘坐
昆明为什么四季如春?冬天温度是多少?
一本书有a页,小林每天看b页,看了8天,用含
夏天白粥明知的红头是什么歌
户口没有问题,都说报满了,踢皮球,内蒙古鄂
一个叶子是什么户外运动品牌
天津脚手架厂家有哪些?
11路公交路线在哪坐呀
2除4的商加上21与3的积,和是多少
5厘米锯一段,锯完后长1厘米的有多少段
魔力宝贝怀旧料理怎么冲技能?每次技能经验是
相亲女孩说我太着急
6年前的电脑能换显卡吗?
五福堂长旺道馆地址在哪,我要去那里办事,
推荐资讯
生女儿是千金,声儿子是啥?
为什么有的车在转方向盘的时候滋滋响
那个1.0的珠子串多少戴手上
想做设计工作,在石家庄刚毕业有实习经验,寻
北京市丰台区宛平城属于几环
饭店黄了 说一个月给开工资 一个月到了 现在
dnf韩服ss调整风华套属性
高中议论文各种话题拟唯美题目
温州半岛公寓酒店怎么样
请教一下变压器的问题 Dy1d2 和 Dy11d0
单选题世界上数量最少的珍稀鸟类是哪一种A.朱
马苏被多少人日过 马苏演的电影 马苏被那个导
正方形一边上任一点到这个正方形两条对角线的
阴历怎么看 ?