仍然老生常谈,在Java中解决并发问题靠的是多线程,但是线程对于Java来说,是一个重量级的对象,为了解决线程切换的成本高的问题,为了解决这个问题,JavaSDK提供线程池并不容易,Java提供了工具类,但是工具类仍然没解决根本的问题,切换成本高,为此,其他的语言提供了一种解决方案, 协程
协程,可以看做是一种轻量级的线程,就是讲原本内核态调度的线程交给了用户态调度,虽然降低了切换的成本,但是导致其线程的栈空间变得极其的小,典型的线程有1M左右,但是协程栈的大小只有几K,故其轻量的多
现在对于协程,实现的比较好的,是Golang语言,我们就拿Golang语言中的协程来看一下
package main
import (
“fmt”
“time”
)
func hello(msg string) {
fmt.Println(“Hello ” + msg)
}
func main() {
//在新的协程中执行hello方法
go hello(“World”)
fmt.Println(“Run in main”)
//等待100毫秒让协程执行结束
time.Sleep(100 * time.Millisecond)
}
对于协程,Thread-Per-Message实现更加简单,容易上手
如果简单的使用Golang,来实现echo的服务端,可以直接为每一个成功的Socket来创建一个协程
package main
import (
“log”
“net”
)
func main() {
//监听本地9090端口
socket, err := net.Listen(“tcp”, “127.0.0.1:9090”)
if err != nil {
log.Panicln(err)
}
defer socket.Close()
for {
//处理连接请求
conn, err := socket.Accept()
if err != nil {
log.Panicln(err)
}
//处理已经成功建立连接的请求
go handleRequest(conn)
}
}
//处理已经成功建立连接的请求
func handleRequest(conn net.Conn) {
defer conn.Close()
for {
buf := make([]byte, 1024)
//读取请求数据
size, err := conn.Read(buf)
if err != nil {
return
}
//回写相应数据
conn.Write(buf[:size])
}
}