这不是家庭作业,而是我在网上发现的面试问题.
Java代码是:
public class SimpleWebServer{
public static void handleRequest(Socket c)
{
//Process the request
}
public static void main(String[] args) throws IOException
{
ServerSocket server=new ServerSocket(80);
while(true)
{
final Socket connection=server.accept();
Runnable task=new Runnable(){
@Override
public void run()
{
handleRequest(connection);
}
};
new Thread(task).start();
}
}
}
问题是高并发性时会出现哪些潜在问题?我的分析是:
>它没有使用synced关键字,因此可能出现竞态条件发生的情况.
>应该使用效率更高的线程池.
>似乎对于每个传入线程,该类总是创建一个新的ServerSocket,当发生高并发性时,它将占用大量空间吗?
解决方法:
我看到的主要问题是您已经确定的问题.每个请求线程模型固有地存在缺陷(Nginx和lighttpd相对于Apache的广泛采用证明了这一点).迁移到ExecutorService(可能由线程池支持)将是一个不错的选择.
通过从每个请求的线程更改为向ExecutorService的简单任务提交,您可以将此应用程序移至基于事件的模型. Web上有很多资料讲授基于事件的模型比基于线程的模型的可伸缩性优点.
在handleRequest方法上使用’synchronized’是一种蛮力策略,并且根据该方法的特殊要求,更细粒度的锁定策略(或无锁定逻辑)将是首选.您提到的ServerSocket创建仅在应用程序中发生一次,因此这实际上不是可伸缩性问题. accept方法的确为每个连接创建了一个新的Socket实例,但这很便宜.查看JDK 6源代码,这包括分配7个布尔值,一个锁对象以及检查一些内部状态-即可能不会有问题.
基本上,您在正确的道路上!希望这可以帮助.
标签:concurrency,java
来源: https://codeday.me/bug/20191030/1971465.html