由于主要用java做web开发,除了以前的在线聊天试验
,对于Object下的wait与notify确实很少使用,并且java中wait与notify都是native的方法,也只能看看api doc,注意下使用事项,总觉得不很踏实,一般来说对于多线程同步问题,最基本的思想就是加锁,其他一切同步机制实际上都是由锁来构造的,那么wait与notify也应该能用锁来实现,近来学习python知道,python中最基本的同步机制就是锁 (Lock),用C实现,而wait与notify则是在锁的基础上用python自身实现,定义在lib/threading.py的Condition类中,看完之后终于对wait机制有了更深刻的理解。
java
简单介绍一下java中的wait以及notify:
首先可以这样理解,每个object实际上自身和一个monitor(锁)关联,
object.wait(timeout) :使当前线程放弃object的锁并等待,除非其它线程调用了object.notify()或者object.notifyAll(),或者使等待线程中断,或者等待了timeout时间
object.notify():随机唤醒一个等待在object的线程 ,该线程和其他活动线程一起争夺object的锁
object.notifyAll():唤醒所有等待在object的线程 ,线程和其他活动线程一起争夺object的锁
根据 java api doc ,使用wait,notify注意事项:
1。调用线程必须已经获得了object的锁,即在synchronized方法或者synchronized(object){}语句块中调用
2。调用线程被唤醒后实际上并不会立即执行后续操作,它要先和其它活动线程竞争获得当前对象的锁,得到对象锁后才能接着执行wait后代码。
python
python对象没有隐式的和一个锁关联,且python中的wait,notify是由python语言自身利用锁(Lock)实现,实现类为Condition,但是概念思想上是和java保留一致,如果要模拟java的话,只需创建python对象时,显式将一个Condition实例赋给创建对象的一个成员属性,那么可以对应java中的doc来看一下python的实现:
threading.py Condition类:
1。wait,notify必须在获得当前对象锁的前提下:
def wait(self, timeout=None):
if not self._is_owned():
raise RuntimeError("cannot wait on un-aquired lock")
.......
def notify(self, n=1):
if not self._is_owned():
raise RuntimeError("cannot notify on un-aquired lock")
.......
可见在wait,notify时都要进行检查,其中self._is_owned()正是判断调用线程是否获得了Condition的内置锁,也即java中对象monitor的概念。
2.wait调用后会使当前线程放弃已经获得对象锁:
def wait(self, timeout=None):
.....
saved_state = self._release_save()
其中 self._release_save正是进行了放弃Condition内置锁的操作,也对应着java先放弃对象monitor的概念
3.wait 使当前线程等待的实现
java doc说明:将当前线程加入object的waitset,然后等待。
python实现为:当前线程在一个新建锁上等待,把改锁加入到condition的等待数组中,线程等待锁的release
def wait(self, timeout=None):
...
#新建一把锁
waiter = _allocate_lock()
#现获得一次,后面再获得就阻测
waiter.acquire()
#记录等待
self.__waiters.append(waiter)
.....
if timeout is None:
#在改锁上等待
waiter.acquire()
if __debug__:
self._note("%s.wait(): got it", self)
4.notify唤醒等待线程实现
同java不同,java notify唤醒的线程不能确定,而python则能确定,一定是第一个调用wait的线程被唤醒,即为先进先出的队列结构。
对于python为:release __waiters等待数组的第一个锁,对应的等待线程即可重新开始在wait函数内运行:
def notify(self, n=1):
....
waiters = __waiters[:n]
for waiter in waiters:
#锁释放,意味着等待锁的对应线程可是从wait函数运行
waiter.release()
try:
__waiters.remove(waiter)
except ValueError:
pass
5.唤醒线程和其他活动线程争夺对象锁
唤醒线程并不是立刻从wait()返回开始它的实际操作,而是要先争夺conditon的内置锁,即java的object monitor:
def wait(self, timeout=None):
#等待在新建锁上
if timeout is None:
waiter.acquire()
#新建锁释放了,但是要先获得condition内置锁才能返回
self._acquire_restore(saved_state)
6.wait的超时处理与notifyAll 略
实例:
分别用java与python实现了经典的生产者与消费者模型
java:
class Q {
int n;
boolean valueSet = false;
/*
如果不同步获得monitor,则会抛出java.lang.IllegalMonitorStateException
*/
/*
同步方式1:By executing a synchronized instance method of that object.
*/
synchronized int get() {
if (!valueSet)
try {
wait();
} catch (InterruptedException e) {
System.out.println("InterruptedException caught");
}
System.out.println("Got: " + n);
valueSet = false;
notify();
return n;
}
/*
如果不同步获得monitor,则会抛出java.lang.IllegalMonitorStateException
*/
void put(int n) {
/*
同步方式2:By executing the body of a synchronized statement
* that synchronizes on the object.
*/
synchronized (this) {
if (valueSet)
try {
wait();
} catch (InterruptedException e) {
System.out.println("InterruptedException caught");
}
this.n = n;
valueSet = true;
System.out.println("Put: " + n);
notify();
}
}
}
class Producer implements Runnable {
Q q;
Producer(Q q) {
this.q = q;
new Thread(this, "Producer").start();
}
public void run() {
int i = 0;
while (i < 7) {
q.put(i++);
}
}
}
class Consumer implements Runnable {
Q q;
Consumer(Q q) {
this.q = q;
new Thread(this, "Consumer").start();
}
public void run() {
int i = 0;
while (i < 7) {
q.get();
i++;
}
}
}
class WaitTest {
public static void main(String args[]) {
Q q = new Q();
new Producer(q);
new Consumer(q);
}
}
python:
# -*- coding: utf-8 -*-
import threading
class Q(object):
def __init__(self):
self.n=0
self.valueSet=False
#相对于java,这里的要自己声明
self.cv=threading.Condition()
def get(self):
cv=self.cv
#先得到锁
cv.acquire()
if not self.valueSet:
cv.wait()
print "Got:",self.n
self.valueSet=False
cv.notify()
#放弃锁
cv.release()
return self.n
def put(self,n):
cv=self.cv
#先得到锁
cv.acquire()
if self.valueSet:
cv.wait()
self.n=n;
self.valueSet=True
print "Put:",n
#放弃锁
cv.notify()
cv.release()
class Producer(threading.Thread):
def __init__(self,q):
threading.Thread.__init__(self)
self.q=q
self.start()
def run(self):
i=0
while i<7:
i+=1
self.q.put(i)
class Consumer(threading.Thread):
def __init__(self,q):
threading.Thread.__init__(self)
self.q=q
self.start()
def run(self):
i=0
while i<7:
i+=1
self.q.get()
if __name__=="__main__":
q=Q()
Producer(q)
Consumer(q)
分享到:
相关推荐
多线程在Java、C++、Python等编程语言中都有广泛的应用。本篇文章将深入探讨多线程执行任务的具体实现方式。 一、线程的概念与优势 线程是操作系统分配CPU时间的基本单元,一个进程可以包含一个或多个线程。相比...
### Python多线程与队列管理Shell程序详解 在Python编程中,多线程和队列管理是非常重要的技术,尤其当涉及到并发处理多个任务时。本文将深入探讨Python中的多线程以及如何利用队列来管理和监控这些线程的状态。 #...
解决了多个进程或者线程对共享资源的争夺 Event e.set e.clear e.wait Lock lock.acquire() lock.release() 4. 什么是线程 threading Thread() t.start() t.join() t.name t.getName t.setName t.daemon...
在Java、Python、C++等编程语言中,都有内置的多线程支持。通过多线程,我们可以充分利用多核处理器的优势,提高程序的响应速度和整体效率。 在Java中,创建线程有多种方式: 1. 继承`Thread`类:自定义一个类继承...
在Java、C++、Python等主流编程语言中,都提供了对多线程的支持。 **线程的创建与管理** 1. **创建线程**:在Java中,可以通过实现Runnable接口或继承Thread类来创建线程。Python中,可以使用`threading`模块创建...
在Java、C#、Python等语言中,都有内置的多线程支持。 多线程的工作原理主要包括以下几个方面: 1. **线程创建**:创建新线程通常通过调用特定函数或方法完成,如Java中的`Thread`类或`Runnable`接口,C#的`Thread`...
标题中的“关于多线程的专用书籍是真的”表明这是一本专门探讨多线程编程的书籍,而描述中的“多线程的专用书籍这是很好的”进一步确认了这本书的专业性和价值。多线程是计算机编程中一个重要的概念,尤其是在并发...
2. 单线程与多线程:单线程程序只有一个执行流,而多线程程序则可以同时处理多个任务,提高了程序的并发性。 3. 并发与并行:并发是指在一段时间内多个任务交替执行,而并行是指在同一时刻多个任务同时执行。多线程...
在Java、C++、Python等编程语言中,都有内置的多线程支持。例如,在Java中,我们可以使用`Thread`类或者`Runnable`接口来创建线程;在C++中,我们可以利用`std::thread`库进行多线程编程;而在Python中,有`...
在Java、Python、C#等编程语言中,都有内置的多线程支持。 描述中提到“可以单独执行一个线程,也可以多个线程同时执行”,这涉及到线程的创建和管理。在Java中,可以使用Thread类或者Runnable接口创建线程,Python...
* 进程 线程 4. 多进程编程 时间片 PCB PID 父子进程 优先级 进程特征 进程状态: 就绪态 运行态 等待态 5. ps -aux ps -ajx pstree top nice 6. os.fork() 7. os.getpid() os.getppid() os._exit() sys.exit() ...
线程通信则是线程间传递信息的方式,如Java中的wait()、notify()和notifyAll()方法,Python中的queue模块等。 **六、死锁** 当两个或更多线程相互等待对方释放资源而无法继续执行时,就会发生死锁。防止和解决死锁...
8. **多线程**:线程的创建、同步、通信方法,如synchronized关键字,wait(), notify(), join()等。 9. **反射机制**:利用反射动态地获取类的信息并操作对象。 10. **JVM内存模型**:了解堆、栈、方法区等内存...
9. **多线程**:Thread类和Runnable接口,同步机制(synchronized关键字、wait/notify等)。 10. **反射机制**:动态获取类信息,创建对象,调用方法的能力。 【Python100道题】可能涵盖Python语言的各种基础到...
在这种情况下,更推荐使用具备多线程或多进程功能的语言,如Python、Java或C++。 总结来说,Shell脚本实现多线程主要是通过后台运行命令或创建子进程来模拟并发执行,适用于简单的任务调度和自动化场景。而实际的多...
5. 多线程:线程创建、同步机制(synchronized、wait()、notify()、Lock接口)。 6. 输入输出流:文件操作、网络通信。 7. Java异常处理:try-catch-finally、throw、throws关键字。 8. Java 核心API:反射、注解、...
同步与死锁是多线程中需要注意的两个问题。同步是指多个线程同时访问共享资源时,需要使用锁机制来避免数据不一致的情况。死锁是指两个或多个线程相互等待对方释放资源,导致程序无法继续执行的情况。 反射机制 ...
* 通过wait waitpid * 通过创建二级子进程,让一级子进程退出 2. multiprocessing创建进程 * Process 类 创建进程对象 * 通过start启动进程 * 通过join回收子进程 ******************************************...
3. **多线程文件搜索实现**:在Java、Python、C#等支持多线程的语言中,可以创建多个线程分别处理不同的文件夹。例如,在Java中,可以使用`Thread`类或`ExecutorService`来创建和管理线程。每个线程负责搜索一个或多...
在Java、Python、C#等编程语言中,都有内置的多线程支持。 在“多线程控制红绿灯变化”的实现中,我们可能使用到的关键概念和技术包括: 1. **线程同步**:为了确保红绿灯交替的正确性,需要对线程进行同步,防止...