文档章节

lock和wait+signal

精通吹水
 精通吹水
发布于 2016/04/15 17:02
字数 830
阅读 267
收藏 15

lock和wait+signal

在编程中,我们经常使用多线程来提升性能,所以这就涉及到互斥和同步的问题了。而在编程中,我们一般都是通过如下方式来完成多线程的互斥和同步:

  • lock | unlock
  • signal + wait(timeout)
  • join
  • sleep

C语言

在Linux C编程中,我们通常使用pthread类库来完成跨平台的多线程控制,如下是几个常用的API:

  • pthread_mutex_lock():占有互斥锁(阻塞操作)
  • pthread_mutex_unlock(): 释放互斥锁
  • pthread_cond_signal(): 唤醒第一个调用pthread_cond_wait()而进入睡眠的线程
  • pthread_cond_wait(): 等待条件变量的特殊条件发生
  • pthread_cond_timedwait():等待条件变量的特殊条件发生或者timeout
  • pthread_join():阻塞当前的线程,直到另外一个线程运行结束
  • sleep() : 休眠固定时间,不过这个API是Linux原生提供,不能跨平台。

注意:**pthread类库是glibc(绝大多数Linux平台标准C库。)的一部分。这些功能都是通过中断号进入内核来完成的,而非仅仅做了Linux兼容API。**具体可见 glibc-2.23\sysdeps\nacl\nacl-interface-list.h ,声明wait(timeout)功能中断号文件。

Java

在Java中,多线程的控制已经是一个统一标准了,一般都是通过Java原生API或者JUC来实现并发控制。这里来说说原生的API:

  • synchronized : 实现了lock 和 unlock的功能
  • Object#wait : 等待信号发生,并且可以实现超时等待
  • Object#notify : 通知信号发生
  • Object#notifyAll :通知信号发生
  • Thread#join :阻塞当前的线程,直到另外一个线程运行结束
  • Thread#sleep : 休眠固定时间

通过这些API,我们基本上能实现Java的多线程并发控制,当然了可以使用最新的JUC并发库的API。而这些API底层也是可以通过pthread这个C库来实现。

示例-Timer

Java中Timer的实现原理就是通过 wait 和 notify 以及 synchronized 来实现的:

Timer timer = new Timer();
timer.schedule(new TimerTask() {
	@Override
	public void run() {

	}
}, 1000);

其实,Timer持有TimerImpl,其实Impl就是一个Thread实现,它一直阻塞等待task的到来,见run代码:

public void run() {
	while (true) {
		TimerTask task;
		synchronized (this) {
			// need to check cancelled inside the synchronized block
			if (cancelled) {
				return;
			}
			//等待任务
			if (tasks.isEmpty()) {
				if (finished) {
					return;
				}
				// no tasks scheduled -- sleep until any task appear
				try {
					//等待任务加入后,会通过notify来通知它可以运行
					this.wait();
				} catch (InterruptedException ignored) {
				}
				continue;
			}
			....
			if (timeToSleep > 0) {
				// sleep!
				try {
					//延迟执行代码
					this.wait(timeToSleep);
				} catch (InterruptedException ignored) {
				}
				continue;
			}

			// no sleep is necessary before launching the task
			...
		}

		...
		try {
			//具体执行任务
			task.run();
			taskCompletedNormally = true;
		} finally {
			...
		}
	}
}

可以看到TimerImpl的run代码会通过wait来阻塞等待任务加入queue,然后通过notify告知它可以运行task。timer#schedule最后会调用TimerImpl#insertTask,具体代码如下:

private void insertTask(TimerTask newTask) {
	// callers are synchronized
	tasks.insert(newTask);
	this.notify();
}

**所以任务加入队列后,通过notify来告知阻塞在等待任务的线程(TimerImpl#run)。**这样子就实现了Timer的功能了,并且通过wait(timeout)实现了delay的功能。

总结

多线程的控制,其实大多都是依赖:

  • lock
  • signal + wait

这两种类型的API来完成并发控制。

而在此基础上,我们可以实现各种各样的多线程并发控制,比如说:MQ,CountDownLatch等。

© 著作权归作者所有

共有 人打赏支持
上一篇: debugger
下一篇: TCP 的那些事儿
精通吹水
粉丝 18
博文 56
码字总数 55035
作品 0
人事招聘
私信 提问
C++11 多线程 Mutex篇 (续)

Mutex篇续 上一篇传送门 std::uniquelock::trylock_until 尝试调用uniquelock所管理的对象(注:该对象也必须支持trylockuntil)的trylockuntil(abstime)给所管理的互斥量上锁. (注:trylockun...

SHIHUAMarryMe
2016/03/19
108
0
Locks in Java(翻译blog)

simple-lock from Java 5 the package java.util.concurrent.locks contains several lock implementations, so you may not have to implement your own locks. But you will still need to......

o0无忧亦无怖
2015/10/08
39
0
MySQL表锁_LOCK TABLES_UNLOCK TABLES

MySQL表锁LOCK TABLESUNLOCK TABLES mysql5.6 参考文档:http://dev.mysql.com/doc/refman/5.6/en/lock-tables.html 锁表和解锁表的基本语法 LOCK TABLES tblname [[AS] alias] locktype [,......

秋风醉了
2014/11/06
0
0
C++11: Mutex和Lock

Mutex全名mutual exclusion(互斥体),是一个可加锁对象(lockable object),用来协助采取独占排他方式控制对资源的并发访问.这里的资源可能是个object,也可能是多个object的组合。为了获得独占式...

SHIHUAMarryMe
2016/03/18
246
0
Intrinsic Locks and Synchronization

Synchronization is built around an internal entity known as the intrinsic lock or monitor lock. (The API specification often refers to this entity simply as a "monitor.") Intrin......

恋空御月
2016/08/19
5
0

没有更多内容

加载失败,请刷新页面

加载更多

MariaDB 服务器在 MySQL Workbench 备份数据的时候出错如何解决

服务器是运行在 MariaDB 10.2 上面的,在使用 MySQL Workbench 出现错误: mysqldump: Couldn't execute 'SELECT COLUMN_NAME, JSON_EXTRACT(HISTOGRAM, '$."number-of-buckets-specified"'......

honeymose
今天
2
0
apache顶级项目(二) - B~C

apache顶级项目(二) - B~C https://www.apache.org/ Bahir Apache Bahir provides extensions to multiple distributed analytic platforms, extending their reach with a diversity of s......

晨猫
今天
6
0
day152-2018-11-19-英语流利阅读

“超级食物”竟然是营销噱头? Daniel 2018-11-19 1.今日导读 近几年来,超级食物 superfoods 开始逐渐走红。不难发现,越来越多的轻食餐厅也在不断推出以超级食物为主打食材的健康料理,像是...

飞鱼说编程
今天
12
0
SpringBoot源码:启动过程分析(二)

接着上篇继续分析 SpringBoot 的启动过程。 SpringBoot的版本为:2.1.0 release,最新版本。 一.时序图 一样的,我们先把时序图贴上来,方便理解: 二.源码分析 回顾一下,前面我们分析到了下...

Jacktanger
昨天
4
0
Apache防盗链配置,Directory访问控制,FilesMatch进行访问控制

防盗链配置 通过限制referer来实现防盗链的功能 配置前,使用curl -e 指定referer [root@test-a test-webroot]# curl -e "http://www.test.com/1.html" -x127.0.0.1:80 "www.test.com/1.jpg......

野雪球
昨天
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部