java实现golang类似的chan
Posted 吴冬冬
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java实现golang类似的chan相关的知识,希望对你有一定的参考价值。
java版本的CSP操作
public class Chan<T>
private T message;
private boolean empty = true;
public synchronized T take()
while (empty)
try
wait();
catch (InterruptedException e)
empty = true;
notifyAll();
return message;
public synchronized void put(T message)
while (!empty)
try
wait();
catch (InterruptedException e)
empty = false;
this.message = message;
notifyAll();
基本的csp操作上面就可以了,但是如果想实现golang的select模型,就要对消息进行改造一下:
class ChanMessage<T>
private String type;
private T data;
public ChanMessage(String type, T data)
this.type = type;
this.data = data;
public String getType()
return type;
public void setType(String type)
this.type = type;
public T getData()
return data;
public void setData(T data)
this.data = data;
public class Chan<T extends ChanMessage>
private T message;
private boolean empty = true;
public synchronized T take()
while (empty)
try
wait();
catch (InterruptedException e)
empty = true;
notifyAll();
return message;
public synchronized void put(T message)
while (!empty)
try
wait();
catch (InterruptedException e)
empty = false;
this.message = message;
notifyAll();
public static void main(String[] args)
Chan<ChanMessage<Integer>> chanMessageChan = new Chan<>();
new Thread(() ->
chanMessageChan.put(new ChanMessage<>("timeout", new Integer(1)));
).start();
new Thread(() ->
ChanMessage<Integer> chanMessage = chanMessageChan.take();
switch (chanMessage.getType())
case "timeout":
System.out.println(chanMessage.getData());
break;
default:
break;
).start();
那么具有缓存的chan当然也好实现了
public class Chan<T extends ChanMessage>
private List<T> lists = new ArrayList<>();
private int size;
public Chan(int size)
this.size = size;
public synchronized T take()
while (lists.size() == 0)
try
wait();
catch (InterruptedException e)
T message = lists.remove(0);
notifyAll();
return message;
public synchronized void put(T message)
while (lists.size() >= size)
try
wait();
catch (InterruptedException e)
lists.add(message);
notifyAll();
来,我们用超时退出试下chan的复用
public static void main(String[] args)
Chan<ChanMessage<Integer>> chanMessageChan = new Chan<>(1);
new Thread(() ->
chanMessageChan.put(new ChanMessage<>("success", new Integer(1)));
chanMessageChan.put(new ChanMessage<>("success", new Integer(2)));
).start();
new Thread(() ->
try
Thread.sleep(1000);
catch (InterruptedException e)
e.printStackTrace();
chanMessageChan.put(new ChanMessage<>("timeout", new Integer(0)));
).start();
new Thread(() ->
while (true)
ChanMessage<Integer> chanMessage = chanMessageChan.take();
switch (chanMessage.getType())
case "success":
System.out.println(chanMessage.getData());
break;
case "timeout":
return;
default:
break;
).start();
对于追求完美的人来说,不介意加点语法糖
static void go(Runnable runnable)
new Thread(runnable).start();
public static void main(String[] args)
Chan<ChanMessage<Integer>> chanMessageChan = new Chan<>(1);
go(() ->
chanMessageChan.put(new ChanMessage<>("success", new Integer(1)));
chanMessageChan.put(new ChanMessage<>("success", new Integer(2)));
);
go(() ->
try
Thread.sleep(1000);
catch (InterruptedException e)
e.printStackTrace();
chanMessageChan.put(new ChanMessage<>("timeout", new Integer(0)));
);
go(() ->
while (true)
ChanMessage<Integer> chanMessage = chanMessageChan.take();
switch (chanMessage.getType())
case "success":
System.out.println(chanMessage.getData());
break;
case "timeout":
return;
default:
break;
);
至此就用java实现了golang的select操作,写完这段代码有种打通了任督二脉的感觉,语言不再是障碍
以上是关于java实现golang类似的chan的主要内容,如果未能解决你的问题,请参考以下文章