黑马程序员技术交流社区
标题:
线程锁的本质是什么?
[打印本页]
作者:
Y_Y
时间:
2013-12-13 22:25
标题:
线程锁的本质是什么?
我想知道线程锁到底是什么,怎么去实现的?
作者:
小斥候
时间:
2013-12-13 22:34
使用线程锁的场合
程序中经常采用多线程处理,这可以充分利用系统资源,缩短程序响应时间,改善用户体验;如果程序中只使用单线程,那么程序的速度和响应无疑会大打折扣。
但是,程序采用了多线程后,你就必须认真考虑线程调度的问题,如果调度不当,要么造成程序出错,要么造成荒谬的结果。
一个讽刺僵化体制的笑话
前苏联某官员去视察植树造林的情况,现场他看到一个人在远处挖坑,其后不远另一个人在把刚挖出的坑逐个填上,官员很费解于是询问陪同人员,当地管理人员说“负责种树的人今天病了”。
上面这个笑话如果发生在程序中就是线程调度的问题,种树这个任务有三个线程:挖坑线程,种树线程和填坑线程,后面的线程必须等前一个线程完成才能进行,而不是按时间顺序来进行,否则一旦一个线程出错就会出现上面荒谬的结果。
用线程锁来处理两个线程先后执行的情况
在程序中,和种树一样,很多任务也必须以确定的先后秩序执行,对于两个线程必须以先后秩序执行的情况,我们可以用线程锁来处理。
线程锁的大致思想是:如果线程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();
}
}
作者:
小斥候
时间:
2013-12-13 22:36
使用线程锁的场合
程序中经常采用多线程处理,这可以充分利用系统资源,缩短程序响应时间,改善用户体验;如果程序中只使用单线程,那么程序的速度和响应无疑会大打折扣。
但是,程序采用了多线程后,你就必须认真考虑线程调度的问题,如果调度不当,要么造成程序出错,要么造成荒谬的结果。
一个讽刺僵化体制的笑话
前苏联某官员去视察植树造林的情况,现场他看到一个人在远处挖坑,其后不远另一个人在把刚挖出的坑逐个填上,官员很费解于是询问陪同人员,当地管理人员说“负责种树的人今天病了”。
上面这个笑话如果发生在程序中就是线程调度的问题,种树这个任务有三个线程:挖坑线程,种树线程和填坑线程,后面的线程必须等前一个线程完成才能进行,而不是按时间顺序来进行,否则一旦一个线程出错就会出现上面荒谬的结果。
用线程锁来处理两个线程先后执行的情况
在程序中,和种树一样,很多任务也必须以确定的先后秩序执行,对于两个线程必须以先后秩序执行的情况,我们可以用线程锁来处理。
线程锁的大致思想是:如果线程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();
}
}
作者:
郭涛
时间:
2013-12-13 22:49
线程锁主要通过关键字synchronized()来实现的
在你所开的线程里加上synchronized(锁)然后用同一把锁,就可以实现多线程中,限制多个线程对同一对象的操作时不会出现重复操作。
就像卖票窗口一样,多个窗口像多个线程,如果不加锁那么可能有两个窗口卖出了同一张票,线程锁就是为防止出现这样的情况而出现的,比如1号窗口卖001号票的时候,别的窗口要等到1号窗口操作完以后才能继续对票数进行操作。
再贴一个以前写的售票例子给你看看
package cn.itcast.thread;
/*
* 需求:铁路售票,一共100张,通过四个窗口卖完.
*/
public class Demo12_Tickets {
/**
* @param args
*/
public static void main(String[] args) {
new TicketsSeller().start();
new TicketsSeller().start();
new TicketsSeller().start();
new TicketsSeller().start();
/*TicketsSeller ts1 = new TicketsSeller();
ts1.start(); //多次启动一个线程是非法的
ts1.start();
ts1.start();
ts1.start();*/
}
}
class TicketsSeller extends Thread {
private static int tickets = 100;
//private static Object obj = new Object();
public void run() {
while (true) {
synchronized (TicketsSeller.class) {
if (tickets <= 0)
break;
try {
Thread.sleep(10);// 1234
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(getName() + "------------这是第" + tickets--
+ "号票");// tickets = tickets - 1
}
}
}
}
复制代码
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2