0 0

线程 与 bufferdReader.readLine5

有问题请教各位:
利用ThreadPoolExecutor做了一个服务器监听socket端口, 关键代码如下:

        private static final int MAX_POOL_SIZE = 100;

        private static final int CORE_POOL_SIZE = 2;
    
        private static final int KEEPALIVE_TIME = 0;
     
	private static final int QUEUE_CAPACITY = (CORE_POOL_SIZE + MAX_POOL_SIZE) / 2;

	private static final TimeUnit TIME_UNIT = TimeUnit.SECONDS;
	
	public static BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<Runnable>(QUEUE_CAPACITY);

	private static ThreadPoolExecutor pool = new ThreadPoolExecutor(CORE_POOL_SIZE,
			MAX_POOL_SIZE, KEEPALIVE_TIME, TIME_UNIT, workQueue,
			new ThreadPoolExecutor.AbortPolicy());

       /** 如监听到便新建一个服务线程pool.execute(new ServerThread());, 服务线程run()如下 */
	public void run(){
		try{
			try{
                /** First, ask them for their name */
				while (true) {
					/** Send the request message */
					this.send("Please enter a name to chat with.");
					/** Run the method to set it, and if set properly, break from the loop */
					String tmp = input.readLine();
					if (null == tmp || "quit".equals(tmp)) {
						Server.workQueue.remove(this);
						this.close();
					}
					if (null != tmp && this.name(tmp)){
						Server.addDescriptor(this);
						break;
					}
					/** Otherwise, well continue... asking again! */
				}

				/** Now, loop so long as we should be waiting for input, and process */
				while (Server.isClosed == false && this.isClosed == false){
					/** Find our input !!! if one client quit, it keeps on sending null */
					String in = input.readLine(); 
					if (null == in || "quit".equals(in)) {
						Server.removeDescriptor(this);
						Server.workQueue.remove(this);
						this.close();
					}
					/** Process it by sending it to everyone else */
					/** get an iterator of descriptors */
					System.out.println("descriptor: " + Server.descriptorList.size());
					Iterator it = Server.descriptorList.iterator();
					/** Iterate over each one */
					while (it.hasNext() && in != null) {
						/** Pull the descriptor from the iterator */
						Descriptor desc = (Descriptor)it.next();
						/** Send the message */
						desc.send(this.getName() + " says '" + in + "'");
					}
				}
			}
			/** Kill the connection on timeout */
			catch (InterruptedIOException iioe){
				/** Log it */
				System.out.println("Timeout occurred - killing connection to " + this.getName());
				/** Send a message */
				this.send("You vanish in a puff of smoke.");
				/** Logout */
				this.logout();
			}
		}
		/** Catch termination of session so we dont get an error */
		catch (IOException ioe){
			System.out.println(getName() + " has logged out");
			// terminate thread at end of run, automatically
		}
	}


假如核心线程为2, 在cmd里telnet服务端口, 头两个服务开启, 运行至String tmp = input.readLine();等待用户输入.
如果再有一用户, 主服务器执行了pool.execute(new ServerThread(), 并把新的线程放入workQueue(size已增加1)中等待, 其它两个线程一直在String tmp = input.readLine();等待, 并没有执行新线程(因为没有打印出this.send("Please enter a name to chat with.");)

当关闭之前2个socket, 在队列中的第三个线程开始执行, 依旧停留于String tmp = input.readLine()

另问: 服务器如何感知客户那边telnet关闭呢? 我在这里只是根据是否收到null

初涉及线程, 帮忙啦
问题补充:
回复llade:
这个能理解, 就因为核心线程全停留在BufferedReader的readLine方法, 就想在等带输入的时候能空出来处理队列的
OO 
2008年6月24日 14:41

1个答案 按时间排序 按投票排序

0 0

线程池中线程的运行顺序是:
corePoolsize达到最大之前(不是maxPoolsize),新加入线程都属于corePoolsize;
corePoolsize达到最大时,所有新加入线程放入blockingQuery。
当blockingQuery满了,则新加入的线程会导致线程池的线程增加,直到maxPoolsize.
当达到maxPoolsize的时候,则调用RejectExecutionHandler来处理了。此处是AbortPolicy,表示抛出RejectedExecutionException异常。


所以你加入的第三个线程会一直等待,除非前两个线程有一个运行完毕。

至于,服务器如何感知客户那边telnet关闭,两个办法,一个
一个是接收某个byte后表示结束,通常是EOF。
一个是服务器这边设置个超时。

2008年6月24日 16:15

相关推荐

    java中br.readLine与br.read的区别.doc

    Java 中 br.readLine 与 br.read 的区别 Java 中的 BufferedReader 类提供了两个常用的读取方法:read() 和 readLine()。这两个方法的作用都是从输入流中读取数据,但是它们的读取方式和返回值类型不同。 read() ...

    原理讲解-ServletInputStream.readLine(byte[] b, int off, int len) 方法

    实际的输出内容取决于读取过程中如何处理每一行数据以及缓冲区大小与实际行长度的关系。 总之,`ServletInputStream.readLine(byte[] b, int off, int len)` 方法是处理 HTTP 请求数据流时的关键工具,特别是在读取...

    C#自定义代码段Console.ReadLine()

    使用方法:VS-代码段管理器-Visual C#-导入本文件,重启VS. VS-C#代码窗内中"crl"+两次tab键 快速调出Console.ReadLine()代码片段

    vs2010 c#控制台 线程实现生产者消费者问题

    绝对好用!福利到了,一分就送 部分代码Console.WriteLine("Please enter how many proceducer:"); p = int.Parse(Console.ReadLine()); Console.WriteLine("Please enter ...整个程序体现了线程的同步与互斥。。。

    详解Python 中sys.stdin.readline()的用法

    6. 对比input():与input()相比,sys.stdin.readline()更多用于原始输入的处理,而input()提供了一个更简洁方便的方式来获取用户输入,并且可以包含提示信息。 实例代码演示了如何使用sys.stdin.readline()来获取...

    readline-6.2.4.1.tar.gz

    - **宏定义与键绑定**:用户可以自定义快捷键,实现特定的功能。 - **多行输入**:在某些应用中,支持多行输入,方便编写复杂的命令。 2. **安装过程**: - **解压源代码**:首先使用 `tar` 命令解压 `readline-...

    BufferedReader的readLine()方法使用时要注意

    `BufferedReader`是Java IO流中的一个类,主要用于读取字符流,它的`readLine()`方法是我们在处理文本数据时经常用到的一个功能,用于逐行读取输入流中的内容。这个方法在处理文件或者网络数据时非常方便,但如果不...

    在VB.NET 读取TXT文件内容按行

    - `line = sr.ReadLine()`: 通过调用`ReadLine`方法来读取文件中的一行内容,并将其存储在`line`变量中。 - `Me.ToolStripStatusLabel2.Text = line`: 将读取的第一行内容赋值给`ToolStripStatusLabel2`的`Text`属性...

    readline-8.0.tar.gz

    `GPU虚拟化` 标签表明这个话题与图形处理单元的虚拟化技术有关。在现代计算中,GPU虚拟化允许多个独立的进程或虚拟机共享同一物理GPU资源,从而提高资源利用率和效率。在AMD平台,可能有一个名为 `gru` 的工具或服务...

    利用开源控件,绘制折线图,功能灵活

    sr.ReadLine(); sr.ReadLine(); sr.ReadLine(); sr.ReadLine(); Regex regex = new Regex("\\s+ ");//空格都归成一个 l13 = regex.Replace(sr.ReadLine(), " ");//读要素行 ll = regex.Replace(sr.ReadLine...

    C#多线程(.pdf)

    #### 二、多线程的优势与劣势 - **优势**: - 提高CPU利用率: 在多线程程序中,当某个线程需要等待时(例如等待I/O操作完成),CPU可以运行其他线程,从而提高程序的整体效率。 - 改善用户体验: 在图形用户界面...

    ReadLine.zip

    在IT行业中,文本处理是日常开发任务中的常见环节,而`ReadLine`是一个在许多编程语言中用于逐行读取文件的重要方法。本篇将详细探讨`ReadLine`的功能、用法以及它在不同编程环境中的应用。 首先,`ReadLine`函数的...

    readline-devel-6.2-11.el7.x86_64.rpm

    readline-devel-6.2-11.el7.x86_64.rpm

    readline-7.0.zip

    包含readline-7.0.tar.gzr和readline-7.0-10.el8.src.rpm两个安装包,可以直接解压tar包编译安装,也可以通过rpm方式安装源码。解压后在源码目录执行以下指令可完成编译和安装: #./configure #make #make install ...

    readline-6.2-11.el7.x86_64.rpm

    readline-6.2-11.el7.x86_64.rpm

    Python 从subprocess运行的子进程中实时获取输出的例子

    这使得在`main.py`中,我们可以通过`p.stdout.readline()`实时读取子进程的输出。 总结来说,Python的`subprocess`模块提供了一种灵活的方式来启动子进程并与之交互。通过`Popen`对象的`stdout`和`stderr`参数,...

    termd:一个开源的终端守护程序库,在ASL 2.0下提供Java中的终端处理

    Readline实施 可扩展,具有可插入功能 多线支持 多字节字符支持 多单元字符支持 Unicode支持 Terminfo功能 支持的协议 远程登录 Termd提供了自己在Netty 4之上编写的Telnet实现。 SSH协议 Termd提供了

    c#递归求和算法

    int n = Convert.ToInt32(Console.ReadLine()); //Console.WriteLine(n.ToString()); int result; Program pg=new Program(); result = aa.fac(n); Console.WriteLine("该数的阶乘为:"+result); Console....

Global site tag (gtag.js) - Google Analytics