学习到golang的channel。总觉得它跟blockingqueue很相似。
然后网上一搜就有这么一句话:
不用使用共享内存来通信,而是用通信来共享内存。
目前我没法理解这句话。不懂什么意思。所以我目前就看使用。
目录
从使用上看channel与queue具有非常大的相似性,甚至能让我觉得几乎都是一种东西,至于什么大的区别我目前没有感觉到。下面就是用java和go实现各自相似的功能。
无缓冲通道与SynchronousQueue
go
s := make(chan int)
go func() {
t.Log("3s 后写入数据",time.Now())
time.Sleep(time.Second * 3)
s <- 8
}()
t.Log(<-s,time.Now())
java
SynchronousQueue sq=new SynchronousQueue();
new Thread(()->{
try {
log.info("3s 后执行");
TimeUnit.SECONDS.sleep(3);
sq.put(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
Object value = sq.take();
log.info("读到数据:"+value.toString());
有缓冲通道与BlockingQueue
go
s:=make(chan int,3)
go func() {
for i:=0;i<7;i++{
s<-i
t.Log("put:",i,time.Now())
time.Sleep(time.Millisecond*300)
}
}()
time.Sleep(time.Second * 3)
for true {
i:= <-s
t.Log("take:",i,time.Now())
}
(注:报错是因为没有go程了,所以系统检测到了死锁)
java
BlockingQueue<Integer> bq =new LinkedBlockingDeque<>(3);
new Thread(()->{
for (int i=0;i<7;i++){
try {
bq.put(i);
log.info("put:"+i);
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
Thread.sleep(1000*3);
while (true){
Integer take = bq.take();
log.info("take:"+take);
}
select与取超时
go
s:=make(chan int,3)
go func() {
for i:=0;i<7;i++{
select {
case s<-i:
t.Log("put:",i,time.Now())
case <-time.After(time.Second):
t.Log("put error:",i,time.Now())
}
}
}()
time.Sleep(time.Second * 3)
for true {
select {
case i:=<-s:
t.Log("take:",i,time.Now())
case <-time.After(2 * time.Second):
t.Log("take is null")
}
}
java
BlockingQueue<Integer> bq =new LinkedBlockingDeque<>(3);
new Thread(()->{
for (int i=0;i<7;i++){
try {
boolean offer = bq.offer(i, 1, TimeUnit.SECONDS);
if(!offer){
log.error("put error:"+i);
}else{
log.info("put:"+i);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
Thread.sleep(1000*3);
while (true){
Integer take = bq.poll(2,TimeUnit.SECONDS);
log.info("take:"+take);
}
java peek查看队首元素,go无对应
java
BlockingQueue<Integer> bq =new LinkedBlockingDeque<>(3);
new Thread(()->{
for (int i=0;i<7;i++){
try {
boolean offer = bq.offer(i, 1, TimeUnit.SECONDS);
if(!offer){
log.error("put error:"+i);
}else{
log.info("put:"+i);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
while (true){
Integer peek = bq.peek();
log.info("peek:"+peek);
TimeUnit.SECONDS.sleep(2);
}
总结
光从使用上它们的用法基本一致,只是语言表达形式不同。