Netty源码------NioEventLoop

目录

Netty源码------NioEventLoop

1、初识 NioEventLoop 

2、NioEventLoop创建

3、NioEventLoop启动

4、NioEventLoop执行过程

5、 Netty 解决JDK 空轮询Bug

6、总结


1、初识 NioEventLoop 

1.1 先来简单回顾一下Netty模型

  • Netty中的Channel系列类型,对应于经典Reactor模型中的client, 封装了用户的通讯连接。
  • Netty中的EventLoop系列类型,对应于经典Reactor模型中的Reactor,完成Channel的注册、轮询、分发。
  • Netty中的Handler系列类型,对应于经典Reactor模型中的Handler,不过Netty中的Handler设计得更加的高级和巧妙,使用了Pipeline模式。

为了简单了解,来个对比吧:

1、单线程模型,来看下面的应用代码:
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
ServerBootstrap server = new ServerBootstrap();
server.group(bossGroup);
2、多线程模型,再来看下面的应用代码:
EventLoopGroup bossGroup = new NioEventLoopGroup(128);
ServerBootstrap server = new ServerBootstrap();
server.group(bossGroup);
3、主从线程模型,到这里相信大家都已经想到了, 实现主从线程模型的代码如下:
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup);

bossGroup 为主线程,而 workerGroup 中的线程是 CPU 核心数乘以 2,因此对应的到 Reactor 线程模型中,我们知

道, 这样设置的 NioEventLoopGroup 其实就是 Reactor 主从多线程模型。

1.2 再来了解一下NioEventLoop 和本地Selector的对应关系

NioEventLoop类型绑定了两个重要的java本地类型:一个线程类型,一个Selector类型。本地Selector属性的作用,用于注册Java本地channel。本地线程属性的作用,主要是用于轮询。

wps565F.tmp

 

1.3 NioEventLoopGroup与NioEventLoop的关系

下面这张图其实是对Netty中NioEventLoop执行的流程图:

  • 从里面可以知道,NioEventLoop就是在NioEventLoopGroup中创建的,一个NioEventLoopGroup可以包含多个NioEventLoop。
  • 它会在Channel注册完之后,调用run()开始工作。详细的内容,下面介绍:

下面进入源码分析: 

2、NioEventLoop创建

从我们常写的代码入手:

public void start() {init();//Netty封装了NIO,Reactor模型,Boss,worker// Boss线程EventLoopGroup bosGroup = new NioEventLoopGroup();//worker工作线程EventLoopGroup workerGroup = new NioEventLoopGroup();try {//相当于Nio中的ServerSocketChannelServerBootstrap server = new ServerBootstrap();//开始设置各种参数server.group(bosGroup, workerGroup)//主线程处理类.channel(NioServerSocketChannel.class)//子线程处理类Handler.childHandler(new ChannelInitializer<SocketChannel>() {protected void initChannel(SocketChannel client) throws Exception {//这里采用了责任链模式进行client.pipeline().addLast(new HttpResponseEncoder()) //编码器.addLast(new HttpRequestDecoder())    //解码器.addLast(new GPTomcatHandler());     //业务逻辑处理}}).option(ChannelOption.SO_BACKLOG, 64)  //针对主线程的配置,分配线程最大数量.childOption(ChannelOption.SO_KEEPALIVE, true); //针对子线程的配置,保吃长连接//启动服务,绑定端口,异步ChannelFuture future = server.bind(port).sync();System.out.println("GP Tomcat 已启动,监听的端口是:" + port);future.channel().closeFuture().sync();} catch (Exception e) {e.printStackTrace();} finally {//关闭线程池bosGroup.shutdownGracefully();workerGroup.shutdownGracefully();}}

从new NioEventLoopGroup() 开始跟踪,我们会依次得到下面的代码:

public NioEventLoopGroup() {this(0);
}public NioEventLoopGroup(int nThreads) {this(nThreads, (Executor) null);
}//线程组默认线程数为2倍的cpu数
//DEFAULT_EVENT_LOOP_THREADS=2*Runtime.getRuntime().availableProcessors()
protected MultithreadEventLoopGroup(int nThreads, Executor executor, Object... args) {super(nThreads == 0 ? DEFAULT_EVENT_LOOP_THREADS : nThreads, executor, args);
}#MultithreadEventExecutorGroup类,核心方法
protected MultithreadEventExecutorGroup(int nThreads, Executor executor,EventExecutorChooserFactory chooserFactory, Object... args) {if (nThreads <= 0) {throw new IllegalArgumentException(String.format("nThreads: %d (expected: > 0)", nThreads));}if (executor == null) {//线程创建器,负责创建NioEventLoopGroup对应底层线程executor = new ThreadPerTaskExecutor(newDefaultThreadFactory());}children = new EventExecutor[nThreads];//创建NioEventLoop对象数组for (int i = 0; i < nThreads; i ++) {boolean success = false;try {//for循环创建每个NioEventLoop,调用newChild(),配置NioEventLoop核心参数children[i] = newChild(executor, args);//newChildsuccess = true;} catch (Exception e) {// TODO: Think about if this is a good exception typethrow new IllegalStateException("failed to create a child event loop", e);} finally {if (!success) {for (int j = 0; j < i; j ++) {children[j].shutdownGracefully();}for (int j = 0; j < i; j ++) {EventExecutor e = children[j];try {while (!e.isTerminated()) {e.awaitTermination(Integer.MAX_VALUE, TimeUnit.SECONDS);}} catch (InterruptedException interrupted) {// Let the caller handle the interruption.Thread.currentThread().interrupt();break;}}}}}//线程选择器,给每个新连接分配NioEventLoop线程chooser = chooserFactory.newChooser(children);final FutureListener<Object> terminationListener = new FutureListener<Object>() {@Overridepublic void operationComplete(Future<Object> future) throws Exception {if (terminatedChildren.incrementAndGet() == children.length) {terminationFuture.setSuccess(null);}}};for (EventExecutor e: children) {e.terminationFuture().addListener(terminationListener);}Set<EventExecutor> childrenSet = new LinkedHashSet<EventExecutor>(children.length);Collections.addAll(childrenSet, children);readonlyChildren = Collections.unmodifiableSet(childrenSet);}#使用threadFactory创建线程
public final class ThreadPerTaskExecutor implements Executor {private final ThreadFactory threadFactory;public ThreadPerTaskExecutor(ThreadFactory threadFactory) {if (threadFactory == null) {throw new NullPointerException("threadFactory");}this.threadFactory = threadFactory;}@Overridepublic void execute(Runnable command) {//每次执行任务创建一个线程,newDefaultThreadFactory定义了nioEventLoop-1-xx的线程名threadFactory.newThread(command).start();}
}

从上面我们可以看出创建NioEventLoopGroup的大致过程如下:

  • 如果没有传入nThread,nThread 默认为CPU核心数的两倍
  • 线程创建器,负责创建NioEventLoopGroup对应底层线程
  • 创建NioEventLoop对象数组,并配置好其的核心参数

接下来,我们进入newChild()方法,也就是配置NioEventLoop核心参数,看看他到底干了些啥事。

#NioEventLoopGroup
@Overrideprotected EventLoop newChild(Executor executor, Object... args) throws Exception {return new NioEventLoop(this, executor, (SelectorProvider) args[0],((SelectStrategyFactory) args[1]).newSelectStrategy(), (RejectedExecutionHandler) args[2]);}NioEventLoop(NioEventLoopGroup parent, Executor executor, SelectorProvider selectorProvider,SelectStrategy strategy, RejectedExecutionHandler rejectedExecutionHandler) {super(parent, executor, false, DEFAULT_MAX_PENDING_TASKS, rejectedExecutionHandler);//父类构造函数if (selectorProvider == null) {throw new NullPointerException("selectorProvider");}if (strategy == null) {throw new NullPointerException("selectStrategy");}provider = selectorProvider;final SelectorTuple selectorTuple = openSelector();selector = selectorTuple.selector;unwrappedSelector = selectorTuple.unwrappedSelector;selectStrategy = strategy;}#SingleThreadEventExecutor类,父类构造函数
protected SingleThreadEventExecutor(EventExecutorGroup parent, Executor executor,boolean addTaskWakesUp, int maxPendingTasks,RejectedExecutionHandler rejectedHandler) {super(parent);this.addTaskWakesUp = addTaskWakesUp;this.maxPendingTasks = Math.max(16, maxPendingTasks);this.executor = ObjectUtil.checkNotNull(executor, "executor");taskQueue = newTaskQueue(this.maxPendingTasks);//task队列,外部线程将任务扔进队列rejectedExecutionHandler = ObjectUtil.checkNotNull(rejectedHandler, "rejectedHandler");}//task queue
protected Queue<Runnable> newTaskQueue(int maxPendingTasks) {// This event loop never calls takeTask()return PlatformDependent.newMpscQueue(maxPendingTasks);
}private SelectorTuple openSelector() {final Selector unwrappedSelector;try {unwrappedSelector = provider.openSelector();} catch (IOException e) {throw new ChannelException("failed to open a new selector", e);}if (DISABLE_KEYSET_OPTIMIZATION) {return new SelectorTuple(unwrappedSelector);}final SelectedSelectionKeySet selectedKeySet = new SelectedSelectionKeySet();//用数组实现setObject maybeSelectorImplClass = AccessController.doPrivileged(new PrivilegedAction<Object>() {@Overridepublic Object run() {try {return Class.forName("sun.nio.ch.SelectorImpl",false,PlatformDependent.getSystemClassLoader());} catch (Throwable cause) {return cause;}}});if (!(maybeSelectorImplClass instanceof Class) ||// ensure the current selector implementation is what we can instrument.!((Class<?>) maybeSelectorImplClass).isAssignableFrom(unwrappedSelector.getClass())) {if (maybeSelectorImplClass instanceof Throwable) {Throwable t = (Throwable) maybeSelectorImplClass;logger.trace("failed to instrument a special java.util.Set into: {}", unwrappedSelector, t);}return new SelectorTuple(unwrappedSelector);}final Class<?> selectorImplClass = (Class<?>) maybeSelectorImplClass;//通过反射方式设置selectedKeySetObject maybeException = AccessController.doPrivileged(new PrivilegedAction<Object>() {@Overridepublic Object run() {try {Field selectedKeysField = selectorImplClass.getDeclaredField("selectedKeys");Field publicSelectedKeysField = selectorImplClass.getDeclaredField("publicSelectedKeys");Throwable cause = ReflectionUtil.trySetAccessible(selectedKeysField);if (cause != null) {return cause;}cause = ReflectionUtil.trySetAccessible(publicSelectedKeysField);if (cause != null) {return cause;}selectedKeysField.set(unwrappedSelector, selectedKeySet);publicSelectedKeysField.set(unwrappedSelector, selectedKeySet);return null;} catch (NoSuchFieldException e) {return e;} catch (IllegalAccessException e) {return e;}}});if (maybeException instanceof Exception) {selectedKeys = null;Exception e = (Exception) maybeException;logger.trace("failed to instrument a special java.util.Set into: {}", unwrappedSelector, e);return new SelectorTuple(unwrappedSelector);}selectedKeys = selectedKeySet;logger.trace("instrumented a special java.util.Set into: {}", unwrappedSelector);return new SelectorTuple(unwrappedSelector,new SelectedSelectionKeySetSelector(unwrappedSelector, selectedKeySet));}

     进行NioEventLoop参数初始化时,干了很多事,但我们重点知道:

  • 创建一个selector,并调用provider.openSelector()创建selector,轮询初始化连接;
  • 创建了一个线程阻塞队列BlockIngqueue<Runable>

接下来我们在回到newChild()方法之后会调用的chooserFactory.newChooser(children);看看它又干了什么大事。

#DefaultEventExecutorChooserFactory 类
public final class DefaultEventExecutorChooserFactory implements EventExecutorChooserFactory {public static final DefaultEventExecutorChooserFactory INSTANCE = new DefaultEventExecutorChooserFactory();private DefaultEventExecutorChooserFactory() { }@SuppressWarnings("unchecked")@Overridepublic EventExecutorChooser newChooser(EventExecutor[] executors) {if (isPowerOfTwo(executors.length)) {return new PowerOfTwoEventExecutorChooser(executors);} else {return new GenericEventExecutorChooser(executors);}}//判断长度是否是2的幂,是则使用PowerOfTwoEventExecutorChooser,更高效private static boolean isPowerOfTwo(int val) {return (val & -val) == val;}private static final class PowerOfTwoEventExecutorChooser implements EventExecutorChooser {private final AtomicInteger idx = new AtomicInteger();private final EventExecutor[] executors;PowerOfTwoEventExecutorChooser(EventExecutor[] executors) {this.executors = executors;}@Overridepublic EventExecutor next() {return executors[idx.getAndIncrement() & executors.length - 1];//&比取模高效,循环下标}}private static final class GenericEventExecutorChooser implements EventExecutorChooser {private final AtomicInteger idx = new AtomicInteger();private final EventExecutor[] executors;GenericEventExecutorChooser(EventExecutor[] executors) {this.executors = executors;}@Overridepublic EventExecutor next() {return executors[Math.abs(idx.getAndIncrement() % executors.length)];//取模}}
}

上面的代码逻辑主要表达的意思是:即如果nThreads 是2 的幂,则使用PowerOfTwoEventExecutorChooser,否则使用GenericEventExecutorChooser。这两个Chooser 都重写next()方法。next()方法的主要功能就是将数组索引循环位移,如下图所示:

  当索引移动最后一个位置时,再调用next()方法就会将索引位置重新指向0。

  这个运算逻辑其实很简单,就是每次让索引自增后和数组长度取模:idx.getAndIncrement() % executors.length。但是就连一个非常简单的数组索引运算,Netty 都帮我们做了优化。因为在计算机底层,&与比%运算效率更高。

     最后,来张时序图总结一下:

3、NioEventLoop启动

NioEventLoop的启动此时是在Channel初始化,并在绑定端口之后开始的。具体可以回顾上篇博客:


Channel的创建:https://blog.csdn.net/qqq3117004957/article/details/106440866#Channel%E6%B3%A8%E5%86%8C
#AbstractBootstrap类doBind方法
private ChannelFuture doBind(final SocketAddress localAddress) {final ChannelFuture regFuture = initAndRegister();final Channel channel = regFuture.channel();if (regFuture.cause() != null) {return regFuture;}if (regFuture.isDone()) {// At this point we know that the registration was complete and successful.ChannelPromise promise = channel.newPromise();doBind0(regFuture, channel, localAddress, promise);return promise;} else {// Registration future is almost always fulfilled already, but just in case it's not.final PendingRegistrationPromise promise = new PendingRegistrationPromise(channel);regFuture.addListener(new ChannelFutureListener() {@Overridepublic void operationComplete(ChannelFuture future) throws Exception {Throwable cause = future.cause();if (cause != null) {// Registration on the EventLoop failed so fail the ChannelPromise directly to not cause an// IllegalStateException once we try to access the EventLoop of the Channel.promise.setFailure(cause);} else {// Registration was successful, so set the correct executor to use.// See https://github.com/netty/netty/issues/2586promise.registered();doBind0(regFuture, channel, localAddress, promise);}}});return promise;}}#AbstractBootstrap类doBind0方法
private static void doBind0(final ChannelFuture regFuture, final Channel channel,final SocketAddress localAddress, final ChannelPromise promise) {// This method is invoked before channelRegistered() is triggered.  Give user handlers a chance to set up// the pipeline in its channelRegistered() implementation.//调用SingleThreadEventExecutor中execute方法channel.eventLoop().execute(new Runnable() {@Overridepublic void run() {if (regFuture.isSuccess()) {channel.bind(localAddress, promise).addListener(ChannelFutureListener.CLOSE_ON_FAILURE);} else {promise.setFailure(regFuture.cause());}}});}#SingleThreadEventExecutor中execute方法
public void execute(Runnable task) {if (task == null) {throw new NullPointerException("task");}boolean inEventLoop = inEventLoop();//判断是否当前eventloop中if (inEventLoop) {addTask(task);} else {startThread();//创建线程addTask(task);if (isShutdown() && removeTask(task)) {reject();}}if (!addTaskWakesUp && wakesUpForTask(task)) {wakeup(inEventLoop);}}public boolean inEventLoop() {return inEventLoop(Thread.currentThread());}public boolean inEventLoop(Thread thread) {return thread == this.thread;}private void startThread() {if (STATE_UPDATER.get(this) == ST_NOT_STARTED) {if (STATE_UPDATER.compareAndSet(this, ST_NOT_STARTED, ST_STARTED)) {doStartThread();}}}//启动线程  
private void doStartThread() {assert thread == null;executor.execute(new Runnable() {@Overridepublic void run() {thread = Thread.currentThread();//保存当前线程,用于判断if (interrupted) {thread.interrupt();}boolean success = false;updateLastExecutionTime();try {SingleThreadEventExecutor.this.run();//触发NioEventLoop执行success = true;} catch (Throwable t) {logger.warn("Unexpected exception from an event executor: ", t);} finally {for (;;) {int oldState = STATE_UPDATER.get(SingleThreadEventExecutor.this);if (oldState >= ST_SHUTTING_DOWN || STATE_UPDATER.compareAndSet(SingleThreadEventExecutor.this, oldState, ST_SHUTTING_DOWN)) {break;}}// Check if confirmShutdown() was called at the end of the loop.if (success && gracefulShutdownStartTime == 0) {logger.error("Buggy " + EventExecutor.class.getSimpleName() + " implementation; " +SingleThreadEventExecutor.class.getSimpleName() + ".confirmShutdown() must be called " +"before run() implementation terminates.");}try {// Run all remaining tasks and shutdown hooks.for (;;) {if (confirmShutdown()) {break;}}} finally {try {cleanup();} finally {STATE_UPDATER.set(SingleThreadEventExecutor.this, ST_TERMINATED);threadLock.release();if (!taskQueue.isEmpty()) {logger.warn("An event executor terminated with " +"non-empty task queue (" + taskQueue.size() + ')');}terminationFuture.setSuccess(null);}}}}});}

NioEventLoop启动流程步骤:

  • bind->execute(task)[入口]:调用NioEventLoop的execute()方法执行绑定端口,操作封装的Task
  • startThread()->doStartThread()[创建线程]:非NioEventLoop线程调用startThread()方法,创建启动线程
  • ThreadPerTaskExecutor.execute():线程执行器执行任务,创建并启动FastThreadLocalThread线程
  • NioEventLoop.run()[启动]

4、NioEventLoop执行过程

在上面doStartThread()方法中最终调用的是SingleThreadEventExecutor.this.run()方法,这个this 就是NioEventLoop 对象:

protected void run() {for (;;) {try {try {switch (selectStrategy.calculateStrategy(selectNowSupplier, hasTasks())) {case SelectStrategy.CONTINUE:continue;case SelectStrategy.BUSY_WAIT:case SelectStrategy.SELECT:select(wakenUp.getAndSet(false));if (wakenUp.get()) {selector.wakeup();}default:}cancelledKeys = 0;needsToSelectAgain = false;final int ioRatio = this.ioRatio;if (ioRatio == 100) {try {processSelectedKeys();} finally {runAllTasks();}          ......}}

终于看到似曾相识的代码。上面代码主要就是用一个死循环,在不断地轮询SelectionKey.select()方法,主要用来解决JDK 空轮询Bug,而processSelectedKeys()就是针对不同的轮询事件进行处理。如果客户端有数据写入,最终也会调用AbstractNioMessageChannel 的doReadMessages()方法。那么我们先来看一下是哪里调用的,通过追踪processSelectedKeys()方法,最后会调用到NioEventLoop的processSelectedKey 方法:

private void processSelectedKey(SelectionKey k, AbstractNioChannel ch) {final AbstractNioChannel.NioUnsafe unsafe = ch.unsafe();if (!k.isValid()) {final EventLoop eventLoop;eventLoop = ch.eventLoop();
int readyOps = k.readyOps();if ((readyOps & SelectionKey.OP_CONNECT) != 0) {int ops = k.interestOps();ops &= ~SelectionKey.OP_CONNECT;k.interestOps(ops);unsafe.finishConnect();}if ((readyOps & SelectionKey.OP_WRITE) != 0) {ch.unsafe().forceFlush();}if ((readyOps & (SelectionKey.OP_READ | SelectionKey.OP_ACCEPT)) != 0 || readyOps == 0) {unsafe.read();}} catch (CancelledKeyException ignored) {unsafe.close(unsafe.voidPromise());}}

  这里可以看到熟悉的代码,当有链接进来的时候,便会走 unsafe.read():这个里面就调用了doReadMessages

  1. Connect, 即连接事件(TCP 连接), 对应于SelectionKey.OP_CONNECT.int值为16.
  2. Accept, 即确认事件, 对应于SelectionKey.OP_ACCEPT.int值为8.
  3. Read, 即读事件, 对应于SelectionKey.OP_READ, 表示 buffer 可读.int值为1
  4. Write, 即写事件, 对应于SelectionKey.OP_WRITE, 表示 buffer 可写.int值为4

总结一下:

  1. Netty 中Selector 事件轮询是从EventLoop 的execute()方法开始的。
  2. 在EventLoop 的execute()方法中,会为每一个任务创建一个独立的线程,并保存到无锁化串行任务队列。
  3. 线程任务队列的每个任务实际调用的是NioEventLoop 的run()方法。
  4. 在run 方法中调用processSelectedKeys()处理轮询事件。

5、 Netty 解决JDK 空轮询Bug

各位应该早有耳闻臭名昭著的Java NIO epoll 的bug,它会导致Selector 空轮询,最终导致CPU 100%。官方声称在JDK1.6 版本的update18 修复了该问题,但是直到JDK1.7 版本该问题仍旧存在,只不过该BUG 发生概率降低了一些而已,它并没有被根本解决。出现此Bug 是因为当Selector 的轮询结果为空,也没有wakeup 或新消息处理,则发生空轮询,CPU 使用率达到100%。

在Netty 中最终的解决办法是:创建一个新的Selector,将可用事件重新注册到新的Selector 中来终止空轮训。前面我们有提到select()方法解决了JDK 空轮训的Bug,它到底是如何解决的呢?下面我们来一探究竟,进入select()方法的源码:

private void select(boolean oldWakenUp) throws IOException {Selector selector = this.selector;try {int selectCnt = 0;long currentTimeNanos = System.nanoTime();long selectDeadLineNanos = currentTimeNanos + delayNanos(currentTimeNanos);for (;;) {          // .......int selectedKeys = selector.select(timeoutMillis);selectCnt ++;if (selectedKeys != 0 || oldWakenUp || wakenUp.get() || hasTasks() || hasScheduledTasks()) {break;}if (Thread.interrupted()) {//.....selectCnt = 1;break;}long time = System.nanoTime();if (time - TimeUnit.MILLISECONDS.toNanos(timeoutMillis) >= currentTimeNanos) {// timeoutMillis elapsed without anything selected.selectCnt = 1;} else if (SELECTOR_AUTO_REBUILD_THRESHOLD > 0 &&selectCnt >= SELECTOR_AUTO_REBUILD_THRESHOLD) {selector = selectRebuildSelector(selectCnt);selectCnt = 1;break;}currentTimeNanos = time;}}

从上面的代码中可以看出,Selector 每一次轮询都计数selectCnt++,开始轮询会计时赋值给timeoutMillis,轮询完成会计时赋值给time,这两个时间差会有一个时间差,而这个时间差就是每次轮询所消耗的时间。从上面的的逻辑看出,如果每次轮询消耗的时间为0,且重复次数超过512 次,则调用rebuildSelector()方法,即重构Selector。

继续跟进源码: 

private void rebuildSelector0() {final Selector oldSelector = selector;final SelectorTuple newSelectorTuple;newSelectorTuple = openSelector();// Register all channels to the new Selector.int nChannels = 0;for (SelectionKey key: oldSelector.keys()) {Object a = key.attachment();try {if (!key.isValid() || key.channel().keyFor(newSelectorTuple.unwrappedSelector) != null) {continue;}int interestOps = key.interestOps();key.cancel();SelectionKey newKey = key.channel().register(newSelectorTuple.unwrappedSelector, interestOps, a);}

在rebuildSelector()方法中,主要做了三件事情:

  1. 创建一个新的Selector。
  2. 将原来Selector 中注册的事件全部取消。
  3. 将可用事件重新注册到新的Selector 中,并激活。

6、总结

说实话,自己总结了这么长,看完都得花半个小时以上,但我认为了解源码并不是为了记住它,而是从中了解Netty的工作机制,有一定的印象就为成功。所以来个小总结:

  • NioEventLoop就相当于NIO编程中的Reactor;
  • 默认的一个NioEventLopGroup会创建CPU核心数的2倍线,即NioEventLoop的数量;
  • NioEventLoop是在Channel注册好之后,调用doBind0()方法开始的;

 

Netty空轮询的解决方法:

netty 会在每次进行 selector.select(timeoutMillis) 之前记录一下开始时间currentTimeNanos,在select之后记录一下结束时间,判断select操作是否至少持续了timeoutMillis秒(这里将time - TimeUnit.MILLISECONDS.toNanos(timeoutMillis) >= currentTimeNanos改成time - currentTimeNanos >= TimeUnit.MILLISECONDS.toNanos(timeoutMillis)或许更好理解一些), 如果持续的时间大于等于timeoutMillis,说明就是一次有效的轮询,重置selectCnt标志,否则,表明该阻塞方法并没有阻塞这么长时间,可能触发了jdk的空轮询bug,当空轮询的次数超过一个阀值的时候,默认是512,就开始重建selector。

 

查看全文
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

相关文章

  1. Java日期

    Date 1.创建一个当前时间表示UTC 时间的日期类 ;UTC时间是:从 1970 年 1 月 1 日 00:00:00 GMT)以来的指定毫秒数。 Date d = new Date();2.Date 对象使用SimpleDateFormat格式化日期, yyyy 是完整的公元年,MM 是月份,dd 是日期,HH:mm:ss 是时、分、秒。注意:有的格式大…...

    2024/4/20 10:52:10
  2. Redis面试问题

    redis面试问题问题一:缓存预热 问题二:缓存雪崩 问题三:缓存击穿 问题四:缓存穿透 问题五:性能指标监控问题一:缓存预热 解决的问题:服务器重启或者刚上线,缓存中没有数据,数据同步、加载等业务量大,服务请求很难得到响应。 总体解决方案:系统启动前,提前将相关的缓…...

    2024/5/7 15:10:03
  3. docker学习(2) 安装和配置docker

    1. 安装docker前准备查看系统内核3.10以上查看系统版本:CentOs 72. 安装docker已写在 https://blog.csdn.net/qq_41957257/article/details/106457807 卸载docker:# 卸载依赖 yum remove docker-ce docker-ce-cli containerd.io#删除资源 rm -rf /var/lib/docker3. 配置阿里…...

    2024/4/24 9:37:02
  4. Leetcode 160. 相交链表

    Leetcode 160. 相交链表1、问题分析2、问题解决3、总结 1、问题分析 题目链接:https://leetcode-cn.com/problems/intersection-of-two-linked-lists/不服就干,直接暴力破解,废话不BB。代码我已经进行了详细的注释,理解应该没有问题,读者可以作为参考,如果看不懂(可以多看…...

    2024/4/24 9:36:59
  5. 浅析-微服务2

    0.学习目标会配置Hystix熔断 会使用Feign进行远程调用 能独立搭建Zuul网关 能编写Zuul的拦截器1.Hystix 1.1.简介 Hystix,即熔断器。 主页:https://github.com/Netflix/Hystrix/ [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-t0hMTaA7-1590565047…...

    2024/4/24 9:36:57
  6. 完全重建QMF滤波器组的设计

    作业一:利用FFT分析信号 分析两个信号:一个信号在前端,另一个信号在后端(相当于第一个信号时移) x1:正态分布的中心点在10,x2:正态分布的中心点在90 matlab实现: clear; clc; close all;N=100; n=[0:1:N-1]; x1=normpdf(n,10,1); x2=normpdf(n,90,1);%绘制原始时域信号…...

    2024/4/24 9:36:56
  7. 刻意练习

    取:https://mp.weixin.qq.com/s/i5PyzXHImEDlRZU8R0WT3A让我们用几个例子,来看一看这个方法的具体应用。 先看第一个例子:读书。 传统的思路,可能是这样的:我今年要读多少本书,要写多少页笔记,要输出多少篇文章……这些不是说不好,但停留在对它们的追逐上,其实意义不大…...

    2024/5/7 21:03:42
  8. 非常好的一篇对linux信号(signal)的解析

    【摘要】本文分析了Linux内核对于信号的实现机制和应用层的相关处理。首先介绍了软中断信号的本质及信号的两种不同分类方法尤其是不可靠信号的原理。接着分析了内核对于信号的处理流程包括信号的触发/注册/执行及注销等。最后介绍了应用层的相关处理,主要包括信号处理函数的安…...

    2024/4/24 9:36:54
  9. java8 stream接口 终端操作 min,max,findFirst,findAny操作

    对于中间操作和终端操作的定义,请看《JAVA8 stream接口 中间操作和终端操作》,这篇主要讲述的是stream的min,max,findFirst,findAny操作,我们先看下函数的定义Optional<T> min(Comparator<? super T> comparator); Optional<T> max(Comparator…...

    2024/4/24 9:36:57
  10. 解决本地vue项目访问服务器api(跨域访问)

    错误:开发环境下的本地vue项目请求获取服务器上的api,服务器上的api不对外开放,只允许内部访问,报错出现跨域访问请求的错误解决: 1、首先,在本地vue项目中的config/index.js中在proxyTable中添加服务器的地址;proxyTable: {//开发环境下的跨域问题解决/api: {target: h…...

    2024/4/24 9:36:52
  11. DPDK源码--KNI实现(十二)

    一、为什么要用kni 通常情况下dpdk用于二三层报文转发,接收到来自网卡的报文后,如果是二层报文则查找fdb表; 如果是三层报文,则进行dnat, snat处理后,查找路由表, 将报文转发给下一跳路由。这些二三层转发操作都是直接转发到另一台设备上,不需要经过内核,无需内核协议栈…...

    2024/4/24 9:36:52
  12. Java日期总结

    Date 1.创建一个当前时间表示UTC 时间的日期类 ;UTC时间是:从 1970 年 1 月 1 日 00:00:00 GMT)以来的指定毫秒数。 Date d = new Date(); 2.Date 对象使用SimpleDateFormat格式化日期, yyyy 是完整的公元年,MM 是月份,dd 是日期,HH:mm:ss 是时、分、秒。注意:有的格式大…...

    2024/4/24 9:36:53
  13. 考研二战日记——第10天小结

    今天帮舍友打印交了几份材料,才意识到,在一个宿舍生活了那么久的兄弟,已经不会再回学校了,没法一块拍毕业照,也没有一顿酒喝出离别的仪式感,大学生活,和大学同学都即将离我而去,这几天变得越来越容易感伤,虽然虽然离离校还有段时间,但是可以明显感受到自己变的越来越…...

    2024/4/24 9:36:50
  14. IOS Block 知识梳理

    1 Block 的定义block 就是以函数以及执行上下文封装起来的对象2 Block 截获对象001 局部变量(基础数据类型)直接获取其值;对象的成员变量连同其所有修饰符一起截获002 静态局部变量 获取的是它的指针形式003 全局变量 不进行截获3.--block 修饰符001 一般情况下被截获的变量…...

    2024/4/15 6:07:41
  15. 744. 寻找比目标字母大的最小字母

    Code char nextGreatestLetter(char* letters, int lettersSize, char target){char answer;for(int i=0;i<lettersSize;i++){if(letters[i]>target){answer = letters[i];return answer;}}return letters[0]; }The easiest way, but a little bit slow....

    2024/4/16 10:28:40
  16. Truthy(真值)非 true

    truthy 值的是在布尔值上下文中,转化后的值为真的值。假值: false 、 0 、 “” 、 null 、 undefined 、 NaN 真值:除以上之外的值。真值示例:if(true)if([]) 空数组if({}) 空对象if(444) 正数if(welcome) 字符串if(new Date()) 构造函数if(-43) 负数if(infinity) 正…...

    2024/4/15 6:07:39
  17. 线性回归和逻辑回归

    最小二乘法假设θ1是年龄的参数,θ2是工资的参数,那么,得到拟合曲线的公式为:真实值和预测值之间会存在一定差异,我们用ε来表示误差,则对于每个样本:假设误差ε(i)是独立的,并且服从均值为0,方差为θ2的正态分布:高斯分布的积分为1,所以可以把闭区间的面积看作概率…...

    2024/4/16 10:29:38
  18. 自考学习,计算机网络原理第二章

    计算机网络应用体系结构 从体系角度可以分为:c/s(客户/服务器)、纯p2p以及混合结构 c/s主要是客户机与服务器之间进行连接,完成数据交换,客户机之间不能进行交流。p2p是没有传统意义上的服务器,每个客户机都既是客户机又是服务器,主要完成客户机之间的交流与信息交换。混…...

    2024/4/16 10:28:20
  19. 线程:整理

    一:线程概述1,进程:正在运行的程序,是系统进行资源分配和调用的独立单位。每一个进程都有它自己的内存空间和系统资源。2,线程:是进程中的单个顺序控制流,是一条执行路径一个进程如果只有一条执行路径,则称为单线程程序。一个进程如果有多条执行路径,则称为多线程程序…...

    2024/4/16 10:29:38
  20. 四.初始化数据库

    一.创建各个微服务相关的数据库按以上格式创建出如下各个数据库:二.初始化webshop_oms库表结构 drop table if exists oms_order;drop table if exists oms_order_item;drop table if exists oms_order_operate_history;drop table if exists oms_order_return_apply;drop tabl…...

    2024/4/16 10:29:38

最新文章

  1. 微服务总结

    推荐你阅读 互联网大厂万字专题总结 Redis总结 JUC总结 操作系统总结 JVM总结 Mysql总结 微服务总结 互联网大厂常考知识点 什么是系统调用 CPU底层锁指令有哪些 AQS与ReentrantLock原理 旁路策略缓存一致性 Java通配符看这一篇就够 Java自限定泛型 分布式架构相比于单体架构具…...

    2024/5/8 6:26:03
  2. 梯度消失和梯度爆炸的一些处理方法

    在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言&#xff0c;在此感激不尽。 权重和梯度的更新公式如下&#xff1a; w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...

    2024/5/7 10:36:02
  3. Ubuntu磁盘扩容

    使用 df -h命令查看系统磁盘控件的使用情况&#xff1a; [samspobosrv:~]$ df -h Filesystem Size Used Avail Use% Mounted on udev 7.8G 0 7.8G 0% /dev tmpfs 1.6G 1.7M 1.…...

    2024/5/6 17:45:24
  4. STL--vector有哪些应用场景

    vector 在 C 中是一种非常灵活和强大的容器&#xff0c;适用于多种不同的应用场景。以下是一些常见的应用场景&#xff1a; 1 动态数据集合&#xff1a;当你不确定数据集的大小&#xff0c;或者数据集的大小会随时间变化时&#xff0c;vector 是理想的选择。例如&#xff0c;在…...

    2024/5/7 5:20:54
  5. 【外汇早评】美通胀数据走低,美元调整

    原标题:【外汇早评】美通胀数据走低,美元调整昨日美国方面公布了新一期的核心PCE物价指数数据,同比增长1.6%,低于前值和预期值的1.7%,距离美联储的通胀目标2%继续走低,通胀压力较低,且此前美国一季度GDP初值中的消费部分下滑明显,因此市场对美联储后续更可能降息的政策…...

    2024/5/8 6:01:22
  6. 【原油贵金属周评】原油多头拥挤,价格调整

    原标题:【原油贵金属周评】原油多头拥挤,价格调整本周国际劳动节,我们喜迎四天假期,但是整个金融市场确实流动性充沛,大事频发,各个商品波动剧烈。美国方面,在本周四凌晨公布5月份的利率决议和新闻发布会,维持联邦基金利率在2.25%-2.50%不变,符合市场预期。同时美联储…...

    2024/5/7 9:45:25
  7. 【外汇周评】靓丽非农不及疲软通胀影响

    原标题:【外汇周评】靓丽非农不及疲软通胀影响在刚结束的周五,美国方面公布了新一期的非农就业数据,大幅好于前值和预期,新增就业重新回到20万以上。具体数据: 美国4月非农就业人口变动 26.3万人,预期 19万人,前值 19.6万人。 美国4月失业率 3.6%,预期 3.8%,前值 3…...

    2024/5/4 23:54:56
  8. 【原油贵金属早评】库存继续增加,油价收跌

    原标题:【原油贵金属早评】库存继续增加,油价收跌周三清晨公布美国当周API原油库存数据,上周原油库存增加281万桶至4.692亿桶,增幅超过预期的74.4万桶。且有消息人士称,沙特阿美据悉将于6月向亚洲炼油厂额外出售更多原油,印度炼油商预计将每日获得至多20万桶的额外原油供…...

    2024/5/7 14:25:14
  9. 【外汇早评】日本央行会议纪要不改日元强势

    原标题:【外汇早评】日本央行会议纪要不改日元强势近两日日元大幅走强与近期市场风险情绪上升,避险资金回流日元有关,也与前一段时间的美日贸易谈判给日本缓冲期,日本方面对汇率问题也避免继续贬值有关。虽然今日早间日本央行公布的利率会议纪要仍然是支持宽松政策,但这符…...

    2024/5/4 23:54:56
  10. 【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响

    原标题:【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响近日伊朗局势升温,导致市场担忧影响原油供给,油价试图反弹。此时OPEC表态稳定市场。据消息人士透露,沙特6月石油出口料将低于700万桶/日,沙特已经收到石油消费国提出的6月份扩大出口的“适度要求”,沙特将满…...

    2024/5/4 23:55:05
  11. 【外汇早评】美欲与伊朗重谈协议

    原标题:【外汇早评】美欲与伊朗重谈协议美国对伊朗的制裁遭到伊朗的抗议,昨日伊朗方面提出将部分退出伊核协议。而此行为又遭到欧洲方面对伊朗的谴责和警告,伊朗外长昨日回应称,欧洲国家履行它们的义务,伊核协议就能保证存续。据传闻伊朗的导弹已经对准了以色列和美国的航…...

    2024/5/4 23:54:56
  12. 【原油贵金属早评】波动率飙升,市场情绪动荡

    原标题:【原油贵金属早评】波动率飙升,市场情绪动荡因中美贸易谈判不安情绪影响,金融市场各资产品种出现明显的波动。随着美国与中方开启第十一轮谈判之际,美国按照既定计划向中国2000亿商品征收25%的关税,市场情绪有所平复,已经开始接受这一事实。虽然波动率-恐慌指数VI…...

    2024/5/7 11:36:39
  13. 【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试

    原标题:【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试美国和伊朗的局势继续升温,市场风险情绪上升,避险黄金有向上突破阻力的迹象。原油方面稍显平稳,近期美国和OPEC加大供给及市场需求回落的影响,伊朗局势并未推升油价走强。近期中美贸易谈判摩擦再度升级,美国对中…...

    2024/5/4 23:54:56
  14. 【原油贵金属早评】市场情绪继续恶化,黄金上破

    原标题:【原油贵金属早评】市场情绪继续恶化,黄金上破周初中国针对于美国加征关税的进行的反制措施引发市场情绪的大幅波动,人民币汇率出现大幅的贬值动能,金融市场受到非常明显的冲击。尤其是波动率起来之后,对于股市的表现尤其不安。隔夜美国股市出现明显的下行走势,这…...

    2024/5/6 1:40:42
  15. 【外汇早评】美伊僵持,风险情绪继续升温

    原标题:【外汇早评】美伊僵持,风险情绪继续升温昨日沙特两艘油轮再次发生爆炸事件,导致波斯湾局势进一步恶化,市场担忧美伊可能会出现摩擦生火,避险品种获得支撑,黄金和日元大幅走强。美指受中美贸易问题影响而在低位震荡。继5月12日,四艘商船在阿联酋领海附近的阿曼湾、…...

    2024/5/4 23:54:56
  16. 【原油贵金属早评】贸易冲突导致需求低迷,油价弱势

    原标题:【原油贵金属早评】贸易冲突导致需求低迷,油价弱势近日虽然伊朗局势升温,中东地区几起油船被袭击事件影响,但油价并未走高,而是出于调整结构中。由于市场预期局势失控的可能性较低,而中美贸易问题导致的全球经济衰退风险更大,需求会持续低迷,因此油价调整压力较…...

    2024/5/4 23:55:17
  17. 氧生福地 玩美北湖(上)——为时光守候两千年

    原标题:氧生福地 玩美北湖(上)——为时光守候两千年一次说走就走的旅行,只有一张高铁票的距离~ 所以,湖南郴州,我来了~ 从广州南站出发,一个半小时就到达郴州西站了。在动车上,同时改票的南风兄和我居然被分到了一个车厢,所以一路非常愉快地聊了过来。 挺好,最起…...

    2024/5/7 9:26:26
  18. 氧生福地 玩美北湖(中)——永春梯田里的美与鲜

    原标题:氧生福地 玩美北湖(中)——永春梯田里的美与鲜一觉醒来,因为大家太爱“美”照,在柳毅山庄去寻找龙女而错过了早餐时间。近十点,向导坏坏还是带着饥肠辘辘的我们去吃郴州最富有盛名的“鱼头粉”。说这是“十二分推荐”,到郴州必吃的美食之一。 哇塞!那个味美香甜…...

    2024/5/4 23:54:56
  19. 氧生福地 玩美北湖(下)——奔跑吧骚年!

    原标题:氧生福地 玩美北湖(下)——奔跑吧骚年!让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 啊……啊……啊 两…...

    2024/5/4 23:55:06
  20. 扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!

    原标题:扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!扒开伪装医用面膜,翻六倍价格宰客!当行业里的某一品项火爆了,就会有很多商家蹭热度,装逼忽悠,最近火爆朋友圈的医用面膜,被沾上了污点,到底怎么回事呢? “比普通面膜安全、效果好!痘痘、痘印、敏感肌都能用…...

    2024/5/5 8:13:33
  21. 「发现」铁皮石斛仙草之神奇功效用于医用面膜

    原标题:「发现」铁皮石斛仙草之神奇功效用于医用面膜丽彦妆铁皮石斛医用面膜|石斛多糖无菌修护补水贴19大优势: 1、铁皮石斛:自唐宋以来,一直被列为皇室贡品,铁皮石斛生于海拔1600米的悬崖峭壁之上,繁殖力差,产量极低,所以古代仅供皇室、贵族享用 2、铁皮石斛自古民间…...

    2024/5/4 23:55:16
  22. 丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者

    原标题:丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者【公司简介】 广州华彬企业隶属香港华彬集团有限公司,专注美业21年,其旗下品牌: 「圣茵美」私密荷尔蒙抗衰,产后修复 「圣仪轩」私密荷尔蒙抗衰,产后修复 「花茵莳」私密荷尔蒙抗衰,产后修复 「丽彦妆」专注医学护…...

    2024/5/4 23:54:58
  23. 广州械字号面膜生产厂家OEM/ODM4项须知!

    原标题:广州械字号面膜生产厂家OEM/ODM4项须知!广州械字号面膜生产厂家OEM/ODM流程及注意事项解读: 械字号医用面膜,其实在我国并没有严格的定义,通常我们说的医美面膜指的应该是一种「医用敷料」,也就是说,医用面膜其实算作「医疗器械」的一种,又称「医用冷敷贴」。 …...

    2024/5/6 21:42:42
  24. 械字号医用眼膜缓解用眼过度到底有无作用?

    原标题:械字号医用眼膜缓解用眼过度到底有无作用?医用眼膜/械字号眼膜/医用冷敷眼贴 凝胶层为亲水高分子材料,含70%以上的水分。体表皮肤温度传导到本产品的凝胶层,热量被凝胶内水分子吸收,通过水分的蒸发带走大量的热量,可迅速地降低体表皮肤局部温度,减轻局部皮肤的灼…...

    2024/5/4 23:54:56
  25. 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...

    解析如下&#xff1a;1、长按电脑电源键直至关机&#xff0c;然后再按一次电源健重启电脑&#xff0c;按F8健进入安全模式2、安全模式下进入Windows系统桌面后&#xff0c;按住“winR”打开运行窗口&#xff0c;输入“services.msc”打开服务设置3、在服务界面&#xff0c;选中…...

    2022/11/19 21:17:18
  26. 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。

    %读入6幅图像&#xff08;每一幅图像的大小是564*564&#xff09; f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...

    2022/11/19 21:17:16
  27. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...

    win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面&#xff0c;在等待界面中我们需要等待操作结束才能关机&#xff0c;虽然这比较麻烦&#xff0c;但是对系统进行配置和升级…...

    2022/11/19 21:17:15
  28. 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...

    有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows&#xff0c;请勿关闭计算机”的提示&#xff0c;要过很久才能进入系统&#xff0c;有的用户甚至几个小时也无法进入&#xff0c;下面就教大家这个问题的解决方法。第一种方法&#xff1a;我们首先在左下角的“开始…...

    2022/11/19 21:17:14
  29. win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...

    置信有很多用户都跟小编一样遇到过这样的问题&#xff0c;电脑时发现开机屏幕显现“正在配置Windows Update&#xff0c;请勿关机”(如下图所示)&#xff0c;而且还需求等大约5分钟才干进入系统。这是怎样回事呢&#xff1f;一切都是正常操作的&#xff0c;为什么开时机呈现“正…...

    2022/11/19 21:17:13
  30. 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...

    Win7系统开机启动时总是出现“配置Windows请勿关机”的提示&#xff0c;没过几秒后电脑自动重启&#xff0c;每次开机都这样无法进入系统&#xff0c;此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一&#xff1a;开机按下F8&#xff0c;在出现的Windows高级启动选…...

    2022/11/19 21:17:12
  31. 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...

    有不少windows10系统用户反映说碰到这样一个情况&#xff0c;就是电脑提示正在准备windows请勿关闭计算机&#xff0c;碰到这样的问题该怎么解决呢&#xff0c;现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法&#xff1a;1、2、依次…...

    2022/11/19 21:17:11
  32. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...

    今天和大家分享一下win7系统重装了Win7旗舰版系统后&#xff0c;每次关机的时候桌面上都会显示一个“配置Windows Update的界面&#xff0c;提示请勿关闭计算机”&#xff0c;每次停留好几分钟才能正常关机&#xff0c;导致什么情况引起的呢&#xff1f;出现配置Windows Update…...

    2022/11/19 21:17:10
  33. 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...

    只能是等着&#xff0c;别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚&#xff0c;只能是考虑备份数据后重装系统了。解决来方案一&#xff1a;管理员运行cmd&#xff1a;net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...

    2022/11/19 21:17:09
  34. 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?

    原标题&#xff1a;电脑提示“配置Windows Update请勿关闭计算机”怎么办&#xff1f;win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢&#xff1f;一般的方…...

    2022/11/19 21:17:08
  35. 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...

    关机提示 windows7 正在配置windows 请勿关闭计算机 &#xff0c;然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;关机提示 windows7 正在配…...

    2022/11/19 21:17:05
  36. 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...

    钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...

    2022/11/19 21:17:05
  37. 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...

    前几天班里有位学生电脑(windows 7系统)出问题了&#xff0c;具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面&#xff0c;长时间没反应&#xff0c;无法进入系统。这个问题原来帮其他同学也解决过&#xff0c;网上搜了不少资料&#x…...

    2022/11/19 21:17:04
  38. 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...

    本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法&#xff0c;并在最后教给你1种保护系统安全的好方法&#xff0c;一起来看看&#xff01;电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中&#xff0c;添加了1个新功能在“磁…...

    2022/11/19 21:17:03
  39. 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...

    许多用户在长期不使用电脑的时候&#xff0c;开启电脑发现电脑显示&#xff1a;配置windows更新失败&#xff0c;正在还原更改&#xff0c;请勿关闭计算机。。.这要怎么办呢&#xff1f;下面小编就带着大家一起看看吧&#xff01;如果能够正常进入系统&#xff0c;建议您暂时移…...

    2022/11/19 21:17:02
  40. 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...

    配置windows update失败 还原更改 请勿关闭计算机&#xff0c;电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;配置windows update失败 还原更改 请勿关闭计算机&#x…...

    2022/11/19 21:17:01
  41. 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...

    不知道大家有没有遇到过这样的一个问题&#xff0c;就是我们的win7系统在关机的时候&#xff0c;总是喜欢显示“准备配置windows&#xff0c;请勿关机”这样的一个页面&#xff0c;没有什么大碍&#xff0c;但是如果一直等着的话就要两个小时甚至更久都关不了机&#xff0c;非常…...

    2022/11/19 21:17:00
  42. 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...

    当电脑出现正在准备配置windows请勿关闭计算机时&#xff0c;一般是您正对windows进行升级&#xff0c;但是这个要是长时间没有反应&#xff0c;我们不能再傻等下去了。可能是电脑出了别的问题了&#xff0c;来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...

    2022/11/19 21:16:59
  43. 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...

    我们使用电脑的过程中有时会遇到这种情况&#xff0c;当我们打开电脑之后&#xff0c;发现一直停留在一个界面&#xff1a;“配置Windows Update失败&#xff0c;还原更改请勿关闭计算机”&#xff0c;等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢&#xff0…...

    2022/11/19 21:16:58
  44. 如何在iPhone上关闭“请勿打扰”

    Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...

    2022/11/19 21:16:57