我这边写的代码不一定规范 但我想足够可以表示出来了
go是最近有学了一段时间了 觉得一些特性(go关键字 内置的channel类型)非常方便
以下是代码:
首先是java的
public void testBlocking() throws InterruptedException{
final BlockingQueue<String> bq=new LinkedBlockingQueue<String>();
final AtomicBoolean isStop=new AtomicBoolean(false);
new Thread(new Runnable() {
@Override
public void run() {
int i=0;
while(true){
while(!bq.offer("物品"+i++)){};
while(!bq.offer("物品"+i++)){};
if(i>=100){
isStop.compareAndSet(false, true);
break;
}
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
while(true){
System.out.println(bq.take());
if(bq.isEmpty()&&isStop.get()){
break;
}
}
}
用了一个堵塞的链表作为传递的对象 为了保证原子性操作 使用了AtomicBoolean这个类
因为i是方法的本地变量 AtomicBoolean可以保证赋值和取值的原子性 只有两个线程的关系 不用加锁和同步块
这个会每隔500毫秒 打印两个物品 一直从物品0到物品99
然后用Go实现的:
package main import( "fmt" "strconv" "time" ) func main (){ item:=make(chan string,10) singal:=make(chan int) var count int go func(item chan<- string,singal chan int){ for{ count++ item<-"物品"+strconv.Itoa(count) count++ item<-"物品"+strconv.Itoa(count) if count<100{ singal<- 1 }else{ singal<- -1 break } time.Sleep(3000*time.Millisecond) } }(item,singal) for{ select { case s:=<-item:{ fmt.Println(s) } case flag:=<-singal:{ if(flag==-1){ goto end } } } } end: }
哪里有错误欢迎指正
不看代码的长度 用了channel的go相对来说理解起来也更加直观 简单.