ringbuffer java例子_Java RingBuffer.publish方法代碼示例「建议收藏」

ringbuffer java例子_Java RingBuffer.publish方法代碼示例「建议收藏」本文整理匯總了Java中com.lmax.disruptor.RingBuffer.publish方法的典型用法代碼示例。如果您正苦於以下問題:JavaRingBuffer.publish方法的具體用法?JavaRingBuffer.publish怎麽用?JavaRingBuffer.publish使用的例子?那麽恭喜您,這裏精選的方法代碼示例或許可以為您提供幫助。您也可以進一步了解該方法…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

本文整理匯總了Java中com.lmax.disruptor.RingBuffer.publish方法的典型用法代碼示例。如果您正苦於以下問題:Java RingBuffer.publish方法的具體用法?Java RingBuffer.publish怎麽用?Java RingBuffer.publish使用的例子?那麽恭喜您, 這裏精選的方法代碼示例或許可以為您提供幫助。您也可以進一步了解該方法所在類com.lmax.disruptor.RingBuffer的用法示例。

在下文中一共展示了RingBuffer.publish方法的23個代碼示例,這些例子默認根據受歡迎程度排序。您可以為喜歡或者感覺有用的代碼點讚,您的評價將有助於我們的係統推薦出更棒的Java代碼示例。

示例1: channelRead0

​點讚 3

import com.lmax.disruptor.RingBuffer; //導入方法依賴的package包/類

@Override

protected void channelRead0(ChannelHandlerContext ctx, O msg) throws Exception {

UUID uuid = CHANNEL_UUID.get(ctx.channel());

if (null != uuid) {

NetSession session = SESSIONS.get(uuid);

if (null != session) {

RingBuffer ringBuffer = THREAD_LOCAL.get().getRingBuffer();

long next = ringBuffer.next();

try {

ConcurrentEvent commandEvent = ringBuffer.get(next);

commandEvent.setValues(newExecutor(session, msg));

} finally {

ringBuffer.publish(next);

}

}

}

}

開發者ID:ogcs,項目名稱:Okra-Ax,代碼行數:18,

示例2: channelRead0

​點讚 3

import com.lmax.disruptor.RingBuffer; //導入方法依賴的package包/類

@Override

protected void channelRead0(ChannelHandlerContext ctx, O msg) throws Exception {

UUID uuid = CHANNEL_UUID.get(ctx.channel());

if (null != uuid) {

Session session = SESSIONS.get(uuid);

if (null != session) {

RingBuffer ringBuffer = THREAD_LOCAL.get().getRingBuffer();

long next = ringBuffer.next();

try {

ConcurrentEvent commandEvent = ringBuffer.get(next);

commandEvent.setValues(newExecutor(session, msg));

} finally {

ringBuffer.publish(next);

}

}

}

}

開發者ID:ogcs,項目名稱:Okra,代碼行數:18,

示例3: stampSequenceIdAndPublishToRingBuffer

​點讚 3

import com.lmax.disruptor.RingBuffer; //導入方法依賴的package包/類

protected final long stampSequenceIdAndPublishToRingBuffer(RegionInfo hri, WALKeyImpl key,

WALEdit edits, boolean inMemstore, RingBuffer ringBuffer)

throws IOException {

if (this.closed) {

throw new IOException(

“Cannot append; log is closed, regionName = ” + hri.getRegionNameAsString());

}

MutableLong txidHolder = new MutableLong();

MultiVersionConcurrencyControl.WriteEntry we = key.getMvcc().begin(() -> {

txidHolder.setValue(ringBuffer.next());

});

long txid = txidHolder.longValue();

try (TraceScope scope = TraceUtil.createTrace(implClassName + “.append”)) {

FSWALEntry entry = new FSWALEntry(txid, key, edits, hri, inMemstore);

entry.stampRegionSequenceId(we);

ringBuffer.get(txid).load(entry);

} finally {

ringBuffer.publish(txid);

}

return txid;

}

開發者ID:apache,項目名稱:hbase,代碼行數:22,

示例4: synchronousFire

​點讚 3

import com.lmax.disruptor.RingBuffer; //導入方法依賴的package包/類

@Override

public void synchronousFire( final Object event ) {

eventCount.increment();

CountDownLatch latch = new CountDownLatch( handlers.size() );

try {

RingBuffer ringBuffer = disruptor.getRingBuffer();

long sequence = ringBuffer.next();

try {

StatisticEventHolder holder = ringBuffer.get( sequence );

holder.set( event );

holder.setLatch( latch );

} finally {

ringBuffer.publish( sequence );

}

latch.await();

} catch ( InterruptedException e ) {

return;

}

}

開發者ID:Tetha,項目名稱:bifroest,代碼行數:20,

示例5: channelRead0

​點讚 2

import com.lmax.disruptor.RingBuffer; //導入方法依賴的package包/類

@Override

protected void channelRead0(ChannelHandlerContext ctx, GpcCall msg) throws Exception {

NetSession session = NET_SESSION_MAP.get(ctx.channel().id());

if (null == session)

return;

RingBuffer ringBuffer = THREAD_LOCAL.get().getRingBuffer();

long next = ringBuffer.next();

try {

ConcurrentEvent commandEvent = ringBuffer.get(next);

commandEvent.setValues(newExecutor(session, msg));

} finally {

ringBuffer.publish(next);

}

}

開發者ID:ogcs,項目名稱:Okra-Ax,代碼行數:15,

示例6: channelRead0

​點讚 2

import com.lmax.disruptor.RingBuffer; //導入方法依賴的package包/類

@Override

protected void channelRead0(ChannelHandlerContext ctx, O msg) throws Exception {

NetSession session = SESSIONS.get(ctx.channel().id());

if (null == session) {

return;

}

RingBuffer ringBuffer = THREAD_LOCAL.get().getRingBuffer();

long next = ringBuffer.next();

try {

ConcurrentEvent commandEvent = ringBuffer.get(next);

commandEvent.setValues(newExecutor(session, msg));

} finally {

ringBuffer.publish(next);

}

}

開發者ID:ogcs,項目名稱:Okra-Ax,代碼行數:16,

示例7: runDisruptorPass

​點讚 2

import com.lmax.disruptor.RingBuffer; //導入方法依賴的package包/類

@Override

protected long runDisruptorPass() throws InterruptedException

{

final CountDownLatch latch = new CountDownLatch(1);

long expectedCount = batchEventProcessor.getSequence().get() + ITERATIONS * BATCH_SIZE;

handler.reset(latch, expectedCount);

executor.submit(batchEventProcessor);

long start = System.currentTimeMillis();

final RingBuffer rb = ringBuffer;

for (long i = 0; i < ITERATIONS; i++)

{

long hi = rb.next(BATCH_SIZE);

long lo = hi – (BATCH_SIZE – 1);

for (long l = lo; l <= hi; l++)

{

rb.get(l).setValue(i);

}

rb.publish(lo, hi);

}

latch.await();

long opsPerSecond = (BATCH_SIZE * ITERATIONS * 1000L) / (System.currentTimeMillis() – start);

waitForEventProcessorSequence(expectedCount);

batchEventProcessor.halt();

failIfNot(expectedResult, handler.getValue());

return opsPerSecond;

}

開發者ID:winwill2012,項目名稱:disruptor-code-analysis,代碼行數:32,

示例8: runDisruptorPass

​點讚 2

import com.lmax.disruptor.RingBuffer; //導入方法依賴的package包/類

@Override

protected long runDisruptorPass() throws InterruptedException

{

final CountDownLatch latch = new CountDownLatch(1);

long expectedCount = poller.getSequence().get() + ITERATIONS;

pollRunnable.reset(latch, expectedCount);

executor.submit(pollRunnable);

long start = System.currentTimeMillis();

final RingBuffer rb = ringBuffer;

for (long i = 0; i < ITERATIONS; i++)

{

long next = rb.next();

rb.get(next).setValue(i);

rb.publish(next);

}

latch.await();

long opsPerSecond = (ITERATIONS * 1000L) / (System.currentTimeMillis() – start);

waitForEventProcessorSequence(expectedCount);

pollRunnable.halt();

failIfNot(expectedResult, pollRunnable.getValue());

return opsPerSecond;

}

開發者ID:winwill2012,項目名稱:disruptor-code-analysis,代碼行數:28,

示例9: runDisruptorPass

​點讚 2

import com.lmax.disruptor.RingBuffer; //導入方法依賴的package包/類

@Override

protected long runDisruptorPass() throws InterruptedException

{

final CountDownLatch latch = new CountDownLatch(1);

long expectedCount = batchEventProcessor.getSequence().get() + ITERATIONS;

handler.reset(latch, expectedCount);

executor.submit(batchEventProcessor);

long start = System.currentTimeMillis();

final RingBuffer rb = ringBuffer;

for (long i = 0; i < ITERATIONS; i++)

{

long next = rb.next();

rb.get(next).setValue(i);

rb.publish(next);

}

latch.await();

long opsPerSecond = (ITERATIONS * 1000L) / (System.currentTimeMillis() – start);

waitForEventProcessorSequence(expectedCount);

batchEventProcessor.halt();

failIfNot(expectedResult, handler.getValue());

return opsPerSecond;

}

開發者ID:winwill2012,項目名稱:disruptor-code-analysis,代碼行數:28,

示例10: runDisruptorPass

​點讚 2

import com.lmax.disruptor.RingBuffer; //導入方法依賴的package包/類

@Override

protected long runDisruptorPass() throws InterruptedException

{

final CountDownLatch latch = new CountDownLatch(1);

long expectedCount = batchEventProcessor.getSequence().get() + ITERATIONS;

handler.reset(latch, ITERATIONS);

executor.submit(batchEventProcessor);

long start = System.currentTimeMillis();

final RingBuffer rb = ringBuffer;

for (long i = 0; i < ITERATIONS; i++)

{

long next = rb.next();

long[] event = rb.get(next);

for (int j = 0; j < event.length; j++)

{

event[j] = i;

}

rb.publish(next);

}

latch.await();

long opsPerSecond = (ITERATIONS * ARRAY_SIZE * 1000L) / (System.currentTimeMillis() – start);

waitForEventProcessorSequence(expectedCount);

batchEventProcessor.halt();

PerfTestUtil.failIf(0, handler.getValue());

return opsPerSecond;

}

開發者ID:winwill2012,項目名稱:disruptor-code-analysis,代碼行數:32,

示例11: runDisruptorPass

​點讚 2

import com.lmax.disruptor.RingBuffer; //導入方法依賴的package包/類

@Override

protected long runDisruptorPass() throws Exception

{

byte[] data = this.data;

final CountDownLatch latch = new CountDownLatch(1);

long expectedCount = processor.getSequence().get() + ITERATIONS;

handler.reset(latch, ITERATIONS);

executor.execute(processor);

long start = System.currentTimeMillis();

final RingBuffer rb = buffer;

for (long i = 0; i < ITERATIONS; i++)

{

long next = rb.next();

ByteBuffer event = rb.get(next);

event.clear();

event.put(data);

event.flip();

rb.publish(next);

}

latch.await();

long opsPerSecond = (ITERATIONS * 1000L) / (System.currentTimeMillis() – start);

waitForEventProcessorSequence(expectedCount);

processor.halt();

return opsPerSecond;

}

開發者ID:winwill2012,項目名稱:disruptor-code-analysis,代碼行數:31,

示例12: publish

​點讚 2

import com.lmax.disruptor.RingBuffer; //導入方法依賴的package包/類

/**

* Publish record task to record special table’s log.

*

* @param struct The table struct.

* @param list The log data list.

*/

public void publish(Struct struct, List list) {

RingBuffer rb = disruptor.getRingBuffer();

long next = rb.next();

try {

LogRecordTask event = rb.get(next);

event.setValues(struct, list);

} finally {

rb.publish(next);

}

}

開發者ID:ogcs,項目名稱:Okra-LOG,代碼行數:17,

示例13: onNext

​點讚 2

import com.lmax.disruptor.RingBuffer; //導入方法依賴的package包/類

public static void onNext(E value, RingBuffer> ringBuffer) {

if (value == null) {

throw SpecificationExceptions.spec_2_13_exception();

}

final long seqId = ringBuffer.next();

final MutableSignal signal = ringBuffer.get(seqId);

signal.type = MutableSignal.Type.NEXT;

signal.value = value;

ringBuffer.publish(seqId);

}

開發者ID:camunda,項目名稱:camunda-bpm-reactor,代碼行數:13,

示例14: onError

​點讚 2

import com.lmax.disruptor.RingBuffer; //導入方法依賴的package包/類

public static void onError(Throwable error, RingBuffer> ringBuffer) {

if (error == null) {

throw SpecificationExceptions.spec_2_13_exception();

}

final long seqId = ringBuffer.next();

final MutableSignal signal = ringBuffer.get(seqId);

signal.type = MutableSignal.Type.ERROR;

signal.value = null;

signal.error = error;

ringBuffer.publish(seqId);

}

開發者ID:camunda,項目名稱:camunda-bpm-reactor,代碼行數:15,

示例15: onComplete

​點讚 2

import com.lmax.disruptor.RingBuffer; //導入方法依賴的package包/類

public static void onComplete(RingBuffer> ringBuffer) {

final long seqId = ringBuffer.next();

final MutableSignal signal = ringBuffer.get(seqId);

signal.type = MutableSignal.Type.COMPLETE;

signal.value = null;

signal.error = null;

ringBuffer.publish(seqId);

}

開發者ID:camunda,項目名稱:camunda-bpm-reactor,代碼行數:11,

示例16: process

​點讚 2

import com.lmax.disruptor.RingBuffer; //導入方法依賴的package包/類

public void process() throws IOException {

try (FastBufferedInputStream stream = new FastBufferedInputStream(inputStreamFactory.get())) {

Preconditions.checkArgument(phaser.getRegisteredParties() == 0);

phaser.register();

disruptor.start();

RingBuffer extends TwoPhaseEvent> ringBuffer = disruptor.getRingBuffer();

long cursor = ringBuffer.next();

LineBytesBuffer buffer = ringBuffer.get(cursor).input();

long lineNo = 0;

ringBuffer.get(cursor).lineNo(lineNo);

boolean needToSkipNext = skipFirst;

while (buffer.readLineFrom(stream)) {

if (needToSkipNext) {

needToSkipNext = false;

continue;

}

lineNo++;

ringBuffer.publish(cursor);

cursor = ringBuffer.next();

buffer = ringBuffer.get(cursor).input();

ringBuffer.get(cursor).lineNo(lineNo);

}

disruptor.shutdown();

phaser.arriveAndAwaitAdvance();

phaser.arriveAndDeregister();

} finally {

afterDisruptorProcessed();

}

}

開發者ID:scaled-ml,項目名稱:Scaled-ML,代碼行數:30,

示例17: main

​點讚 2

import com.lmax.disruptor.RingBuffer; //導入方法依賴的package包/類

public static void main(String[] args) {

final List handlers = new ArrayList<>(NUMBER_CONSUMERS);

RingBuffer ringBuffer = RingBuffer.createSingleProducer(

ValueEvent.EVENT_FACTORY, RING_SIZE, new SleepingWaitStrategy());

start = System.nanoTime();

//Create consumers

for(int i = 0; i < NUMBER_CONSUMERS; i++) {

ValueEventHandler1PMC handler = new ValueEventHandler1PMC(start, handlers);

handlers.add(handler);

SequenceBarrier barrier = ringBuffer.newBarrier();

BatchEventProcessor eventProcessor = new BatchEventProcessor(

ringBuffer,barrier, handler);

ringBuffer.addGatingSequences(eventProcessor.getSequence());

// Each EventProcessor can run on a separate thread

EXECUTOR.submit(eventProcessor);

}

for(int i = 0; i < SAMPLES_SIZE; i++) {

// Publishers claim events in sequence

long sequence = ringBuffer.next();

ValueEvent event = ringBuffer.get(sequence);

event.setValue(i); // this could be more complex with multiple fields

// make the event available to EventProcessors

ringBuffer.publish(sequence);

}

}

開發者ID:iproduct,項目名稱:low-latency-high-throughput,代碼行數:35,

示例18: channelRead0

​點讚 2

import com.lmax.disruptor.RingBuffer; //導入方法依賴的package包/類

@Override

protected void channelRead0(ChannelHandlerContext ctx, O msg) throws Exception {

Session session = SESSIONS.get(ctx.channel().id());

if (null == session) {

return;

}

RingBuffer ringBuffer = THREAD_LOCAL.get().getRingBuffer();

long next = ringBuffer.next();

try {

ConcurrentEvent commandEvent = ringBuffer.get(next);

commandEvent.setValues(newExecutor(session, msg));

} finally {

ringBuffer.publish(next);

}

}

開發者ID:ogcs,項目名稱:Okra,代碼行數:16,

示例19: fire

​點讚 2

import com.lmax.disruptor.RingBuffer; //導入方法依賴的package包/類

@Override

public void fire( final Object event ) {

eventCount.increment();

RingBuffer ringBuffer = disruptor.getRingBuffer();

long sequence = ringBuffer.next();

try {

StatisticEventHolder holder = ringBuffer.get( sequence );

holder.set( event );

holder.setLatch( null );

} finally {

ringBuffer.publish( sequence );

}

}

開發者ID:Tetha,項目名稱:bifroest,代碼行數:14,

示例20: run

​點讚 2

import com.lmax.disruptor.RingBuffer; //導入方法依賴的package包/類

@Override

public void run(){

_logger.info(“Node run starting…”);

Executor executor = Executors.newCachedThreadPool();

Disruptor disruptor = new Disruptor<>(SurfEvent.EVENT_FACTORY, 128, executor);

disruptor.handleEventsWith(this);

RingBuffer buffer = disruptor.start();

VDSEventListImpl events = null;

while(!_shutdown){

try{

events = _eventListPool.borrowObject(0);

while(events.getEventsList().isEmpty()) {

_source.read(events);

}

if(_needsAck){

Object obj = _acksource.getInputObject();

// Hacking this in for now

// Need to actually ack the object after Kinesis consumes it: TODO

_acksource.updateInputObject(obj);

}

long seq = buffer.next();

SurfEvent event = buffer.get(seq);

event.setEventlist(events);

buffer.publish(seq);

}

catch(Exception ex){

_logger.error(“Exception while reading data:”, ex);

ex.printStackTrace();

}

}

}

開發者ID:InformaticaCorp,項目名稱:Surf,代碼行數:34,

示例21: publishExchangeOnRingBuffer

​點讚 2

import com.lmax.disruptor.RingBuffer; //導入方法依賴的package包/類

private void publishExchangeOnRingBuffer(final Exchange exchange,

final RingBuffer ringBuffer) {

final long sequence = ringBuffer.next();

ringBuffer.get(sequence).setExchange(exchange, uniqueConsumerCount);

ringBuffer.publish(sequence);

}

開發者ID:HydAu,項目名稱:Camel,代碼行數:7,

示例22: tryPublishExchangeOnRingBuffer

​點讚 2

import com.lmax.disruptor.RingBuffer; //導入方法依賴的package包/類

private void tryPublishExchangeOnRingBuffer(final Exchange exchange, final RingBuffer ringBuffer) throws InsufficientCapacityException {

final long sequence = ringBuffer.tryNext();

ringBuffer.get(sequence).setExchange(exchange, uniqueConsumerCount);

ringBuffer.publish(sequence);

}

開發者ID:HydAu,項目名稱:Camel,代碼行數:6,

示例23: main

​點讚 2

import com.lmax.disruptor.RingBuffer; //導入方法依賴的package包/類

public static void main(String[] args) {

RingBuffer ringBuffer = RingBuffer.createSingleProducer(

ValueEvent.EVENT_FACTORY, RING_SIZE, new SleepingWaitStrategy());

start = System.nanoTime();

//Create first consumer

ValueEventHandler1PMCSequenceFirst handler = new ValueEventHandler1PMCSequenceFirst(start);

SequenceBarrier barrier;

barrier = ringBuffer.newBarrier();

BatchEventProcessor firstEventProcessor = new BatchEventProcessor(

ringBuffer,barrier, handler);

//ringBuffer.addGatingSequences(firstEventProcessor.getSequence());

// Each EventProcessor can run on a separate thread

EXECUTOR.submit(firstEventProcessor);

//Create second consumer

ValueEventHandler1PMCSequenceSecond handler2 = new ValueEventHandler1PMCSequenceSecond(start);

SequenceBarrier barrier2 = ringBuffer.newBarrier(firstEventProcessor.getSequence());

BatchEventProcessor secondEventProcessor = new BatchEventProcessor(

ringBuffer,barrier2, handler2);

ringBuffer.addGatingSequences(secondEventProcessor.getSequence());

// Each EventProcessor can run on a separate thread

EXECUTOR.submit(secondEventProcessor);

for(int i = 0; i < SAMPLES_SIZE; i++) {

// Publishers claim events in sequence

long sequence = ringBuffer.next();

ValueEvent event = ringBuffer.get(sequence);

event.setValue(i); // this could be more complex with multiple fields

// make the event available to EventProcessors

ringBuffer.publish(sequence);

}

}

開發者ID:iproduct,項目名稱:low-latency-high-throughput,代碼行數:42,

注:本文中的com.lmax.disruptor.RingBuffer.publish方法示例整理自Github/MSDocs等源碼及文檔管理平台,相關代碼片段篩選自各路編程大神貢獻的開源項目,源碼版權歸原作者所有,傳播和使用請參考對應項目的License;未經允許,請勿轉載。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/195233.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 关于Laravel中使用response()方法调用json()返回数据unicode编码转换的问题解决

    关于Laravel中使用response()方法调用json()返回数据unicode编码转换的问题解决

  • 关于IO流的笔试面试题[通俗易懂]

    关于IO流的笔试面试题[通俗易懂]1.java中有几种类型的流?jdk为每种类型的流提供了一些抽象类以供继承,请说出它们分别是什么?解题思路:了解io流的体系(重要)就可以了从大的方面来分可以分为字节流和字符流.字符流提供了提供了reader和writer;字节流提供了outputstream 和inputstream. 2.字符流和字节流有什么区别?(重要)解题思路:从读写的原理上来进行区分会好记一点(字符流…

  • Firefly支持AI引擎Tengine,性能提升,轻松搭建AI计算框架

    Firefly支持AI引擎Tengine,性能提升,轻松搭建AI计算框架

  • 分布式系统常见问题总结[通俗易懂]

    分布式系统常见问题总结[通俗易懂]秒杀系统架构优化思路一、秒杀业务为什么难做1)im系统,例如qq或者微博,每个人都读自己的数据(好友列表、群列表、个人信息);2)微博系统,每个人读你关注的人的数据,一个人读多个人的数据;3)秒杀系统,库存只有一份,所有人会在集中的时间读和写这些数据,多个人读一个数据。例如:小米手机每周二的秒杀,可能手机只有1万部,但瞬时进入的流量可能是几百几千万。又例如:12306抢票,…

  • Android触屏事件流[通俗易懂]

    Android触屏事件流[通俗易懂]一次触屏事件分为三个动作ACTION_DOWN,ACTION_MOVE和ACTION_UP。其中ACTION_DOWN和ACTION_UP在一次触屏事件中只会触发一次,ACTION_MOVE可能触发任意次(包括0次)。主要响应触屏的组件有两种,一种是可以包含子元素的(ViewGroup比如LinearLayout),另一种是不能包含子元素的View(最底层的View比

  • (20211130更新)关于jupyter notebook的下载安装及自己的配置、主题

    什么是jupyternotebook?JupyterNotebook是基于网页的用于交互计算的应用程序。其可被应用于全过程计算:开发、文档编写、运行代码和展示结果。打开的好慢。。没事,我们就不讲官网的了。JupyterNotebook以命令行启动后,以网页的形式打开,我们可以在网页页面中直接编写代码和运行代码,运行代码块后,运行结果会直接在代码块下显示。比如这样:当然我们在编程过程中会习惯的编写注释,可在同一个页面中直接编写。安装由于时间关系,我就先讲解一下本人的安装及使用,关于

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号