协程 及yield回顾

yield回顾

import time
import queue


def consumer(name):
    print("--->starting eating baozi...")
    while True:
        print('befor yield')
        new_baozi = yield
        print('after yield')
        print("[%s] is eating baozi %s" % (name, new_baozi))
        # time.sleep(1)


def producer():
    next(con)
    next(con2)
    n = 0

    time.sleep(5)
    while n < 2:
        n += 1
        con.send(n)
        con2.send(n)
        print("\033[32;1m[producer]\033[0m is making baozi %s" % n)


if __name__ == '__main__':
    con = consumer("c1")
    con2 = consumer("c2")
    producer()

程序主要目的为实现producer和consumer两个函数在一个线程同时运行,并通过yield交互,达到单进程中的并行效果。
new_baozi = yield
这句的意思是,将send的结果通过yield返回给neu_baozi,此时程序阻塞在此,知道send执行。
进而实现了并行。当consumer继续运行后又在此阻塞在次,进而等待send

已知的问题,当producer sleep时整个协程会直接block阻塞。故使用gevent解决。

GEVENT

import gevent

def func1():
    print('\033[31;1min func1 start...\033[0m')
    gevent.sleep(2)
    print('\033[31;1mback to func1...\033[0m')


def func2():
    print('\033[32;1min func2 start...\033[0m')
    gevent.sleep(1)
    print('\033[32;1mback to func2...\033[0m')

def func3():
    print('\033[32;1min func3 start...\033[0m')
    gevent.sleep(1)
    print('\033[32;1mback to func3...\033[0m')

gevent.joinall([
    gevent.spawn(func1),
    gevent.spawn(func2),
    gevent.spawn(func3),
])


# C:\Python35\python.exe D:/python/oldboy/DAY09/coroutine_01.py
# in func1 start...
# in func2 start...
# in func3 start...
# back to func2...
# back to func3...
# back to func1...
#
# Process finished with exit code 0

gevent.joinall([
gevent.spawn(func1),
gevent.spawn(func2),
gevent.spawn(func3),
])
程序采用如上方法调用各个函数,通过
gevent.sleep(1)
通过gevent的sleep来实现sleep不阻塞。

单线程实现爬虫并发

from gevent import monkey;

monkey.patch_all()
import gevent
from  urllib.request import urlopen


def f(url):
    print('GET: %s' % url)
    resp = urlopen(url)
    data = resp.read()
    print('%d bytes received from %s.' % (len(data), url))


gevent.joinall([
    gevent.spawn(f, 'https://weibo.com/'),
    gevent.spawn(f, 'https://www.baidu.com/'),
    gevent.spawn(f, 'https://github.com/'),
])

其中如下语句为取消所有阻塞,从而达到并发。

monkey.patch_all()

同步与异步效率对比


import gevent

def task(pid):
    gevent.sleep(0.5)
    print('Task %s done' % pid)

def synchronous():
    for i in range(1, 10):
        task(i)

def asynchronous():
    threads = [gevent.spawn(task, i) for i in range(1, 10)]
    gevent.joinall(threads)

print('Synchronous:')
synchronous()

print('Asynchronous:')
asynchronous()

GEVENT实现socket并发

#   SERV
# import sys
import time
import socket

import gevent
from gevent import monkey
from gevent import socket

monkey.patch_all()

def server(port):
    s = socket.socket()
    s.bind(('0.0.0.0', port))
    s.listen(20)

    while True:
        cli, addr = s.accept()
        gevent.spawn(handle_request, cli)

def handle_request(conn):
    try:
        while True:
            data = conn.recv(1024)
            print("recv:", data)
            conn.send(data)
            if not data:
                conn.shutdown(socket.SHUT_WR)
    except Exception as ex:
        print(ex)

    finally:
        conn.close()

if __name__ == '__main__':
    server(8001)

#   CLI
import socket

HOST = 'localhost'
PORT = 8001
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))

while True:
    msg = bytes(input(">>:"), encoding='utf-8')
    s.sendall(msg)
    data = s.recv(1024)

    print('Recieve', data)

s.close()
 本套课程分为基础与中级两部分,分别就lua语言的各方面知识点进行探讨,学习完本套课程,对于后续Xlua(Tolua等框架)技术的学习提供强大的语言技术保证。       本套lua课程采用入门与商业级两种开发IDE进行教学:入门级的SciTE内置IDE与商业级的IDEA lua插件。本套课程学习完毕,对于除了传统手游外,在VR、AR、商业级大型应用程序、嵌入式设备开发等领域都有较强的指导作用。           《lua中级篇》分为:“函数的进阶”、“字符串进阶”、“Table进阶”、“元表”、“OOP面向对象”、“协同程序”、“IO操作”、“调试与运行”等八个大的章节,详细深入讲解lua开发的方方面面。        内容包含lua可变参数、闭包、模块、函数尾调用、字符串模式匹配、字符串不变性原理、矩阵、链表、元表详解与应用、协同的生命周期与生产消费者问题、lua文件各种读写操作、lua执行外部代码与错误异常处理垃圾收集机制等。       最后,lua中级篇的学习,对于广大学员开发商业级lua热更新技术,具有不可替代的重要作用! 热更新系列(技术含量:中高级):B:《热更新框架设计之Xlua基础视频课程》https://edu.youkuaiyun.com/course/detail/27110C:《热更新框架设计之热更流程与热补丁技术》https://edu.youkuaiyun.com/course/detail/27118D:《热更新框架设计之客户端热更框架(上)》https://edu.youkuaiyun.com/course/detail/27132E:《热更新框架设计之客户端热更框架(中)》https://edu.youkuaiyun.com/course/detail/27135F:《热更新框架设计之客户端热更框架(下)》https://edu.youkuaiyun.com/course/detail/27136 
<think>好的,我现在需要回答用户关于Java中协程实现方式、库以及使用教程的问题。首先,我得回顾一下用户提供的引用内容,看看有没有相关的信息可以利用。 根据引用[1],Java平台之前主要依赖内核线程实现的Thread类,但现在引入了续体(continuation)的支持,可以与ForkJoinPool等调度器结合使用来实现协程。这说明Java本身在协程方面有了一些底层支持,可能通过Project Loom来实现。引用[3]提到传统多线程的切换开销大,而协程提供了更高效的并发模型。这里需要对比Java的线程和协程的区别,强调协程的优势。 引用[4]提到了Protothreads,但这是嵌入式系统的协程模型,可能和Java关系不大。不过用户问的是Java相关的库,所以可能需要提到第三方库如Quasar或Kilim。引用[5]是关于Kotlin协程的,但用户明确问的是Java,所以可能需要说明Kotlin在JVM上的协程实现,或者Java中是否有类似的库。 接下来,我需要整理Java中协程的实现方式。首先,Project Loom是OpenJDK的项目,引入了虚拟线程,也就是协程。然后,第三方库如Quasar使用字节码增强,Kilim使用类似的方法,需要代理运行。还有像EA Async这样的库,虽然不完全是协程,但提供了异步编程的支持。此外,Kotlin协程也可以在Java项目中使用,但可能需要混合编程。 在使用教程部分,需要分点说明不同实现方式的具体步骤,比如使用Project Loom需要下载早期版本,添加依赖,然后编写代码示例。对于Quasar,要说明如何添加依赖,使用@Suspendable注解和Fiber类。对于Kotlin协程,则要展示如何在Java中调用,但可能会有些限制。 最后,生成相关问题,比如Java协程与传统线程的区别,性能对比,以及与其他语言的对比等。确保引用正确的来源,比如引用1和3提到协程的优势,引用5提到launch函数的使用。 需要注意用户提到的系统级指令,比如数学公式用$...$,但这个问题可能不涉及数学公式。回答要结构清晰,分点说明,引用正确,并添加相关问题。</think>### Java协程实现方式与库详解 Java协程的实现主要分为**平台级支持**和**第三方库**两类,以下是详细分析: --- #### 一、Java平台级协程支持(Project Loom) 1. **虚拟线程(Virtual Threads)** Project Loom通过引入虚拟线程(协程)来简化并发编程。虚拟线程由JVM直接管理,而非依赖操作系统线程,显著降低线程切换开销[^1]。 ```java try (var executor = Executors.newVirtualThreadPerTaskExecutor()) { executor.submit(() -> System.out.println("Hello from virtual thread!")); } ``` - 特点:无需修改代码即可兼容传统`Thread` API,支持百万级线程创建[^3]。 - 要求:需使用JDK 19+并启用预览特性。 2. **续体(Continuation)** Loom通过`Continuation`类实现协程的挂起与恢复,开发者可通过`yield()`手动控制执行流程[^1]。 --- #### 二、第三方协程库 1. **Quasar** - **实现原理**:基于字节码增强(通过Java Agent),在方法调用处插入挂起/恢复逻辑[^4]。 - 示例代码: ```java @Suspendable public void coroutineTask() throws SuspendExecution { Fiber.park(1000); // 挂起1秒 System.out.println("Resumed"); } new Fiber<>(this::coroutineTask).start(); ``` - **依赖**:需添加Java Agent参数`-javaagent:quasar-core.jar`。 2. **Kilim** - 通过注解`@Yieldable`和`Task`类实现协程,类似Quasar但更轻量。 - 适用场景:I/O密集型任务,如网络通信。 3. **EA Async** - 微软开发的异步编程库,通过`CompletableFuture`简化协程式编码: ```java async(()->{ await(CompletableFuture.runAsync(()->{})); return "Done"; }); ``` --- #### 三、Kotlin协程与Java互操作 虽然Kotlin协程(如`launch`函数)主要面向Kotlin[^5],但可通过混合编程在Java中调用: ```java // Kotlin侧定义挂起函数 suspend fun fetchData(): String { /* ... */ } // Java侧调用 CoroutineScope scope = new CoroutineScope(Dispatchers.getIO()); scope.launch(() -> { String result = fetchData(); }); ``` --- #### 四、使用建议 1. **新项目**:优先采用Project Loom,其为Java官方且无侵入性。 2. **遗留系统**:若需轻量级方案,可选择Quasar或Kilim。 3. **异步优化**:结合CompletableFuture与EA Async减少回调嵌套。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值