早期很多绑定unix的ftp服务器和第三方ftp服务器,都会为每个连接创建(fork)一个新的进程。100个并发用户意味着要处理100个额外进程。由于进程是重量级的,太多进程会让服务器吃不消。
早期web服务器也有这个问题,不过http连接的短暂性而掩盖了一些。当使用增长时,web服务器的性能仍会下降。
这个问题的方案有两个:
1、使用数据库连接池或者进程池或者线程池的作用是?
没有池,每一个请求需要创建一次链接,使用完进行销毁。
创建池后,池内有一定数量的池连接。入站请求放入队列。每个进程从队列中删除一个请求,为这个请求提供服务。作用是:减少创建和销毁的过程,提升效率。大概300条进程池能完成相当于1000条进程默认的任务。(大概3倍)
2、线程与进程
一个进程包含多个线程。
每个进程在不同的内存区域。所以开销比较大,占用资源多。
每个线程使用相同的内存区域。所以开销比较小,占用资源少。
所以使用线程代替进程,可以让你的服务器性能提高3倍。使用可重用的线程池(不是可重用的进程池),服务器可以运行9倍快。
这种性能的提升给程序员开发带来了复杂性,因为线程共享内存所以使用时会产生对另一个线程数据结构的改变。因此有时需要线程同步,确保线程安全性和生命周期。如果一个程序中没有内存保护机制的操作系统(如mac os9,windows 95)中运行,也会以类是的方式破坏整个系统。
还有一种解决方案 也是效率最高的,适用java1.4及以后的版本。利用选择器(selector)
具体什么情况下使用线程:例如,计算多个文件的安全散列算法(SHA),这个程序是受限于I/O的,既程序的速度会受到从磁盘上读取文件所花费时间的限制。或者网络程序,程序运行的速度要比网络提供输入的速度快,因此很多阻塞的时间久白白耗费了。这些时间本可以被其他线程所用。
-------------
servlet是单实列,多线程。规范规定通常容器对单个jvm只建立一个servlet实例。
1.对于一个servlet,每个用户请求将生成新的线程。
2.当首次创建servlet时就会调用init()方法,而并不是每个用户请求都调用该方法。
3.当每个用户请求servlet时,都会调用server方法
线程在run()方法开始,run()方法结束。
单线程程序在main()方法返回时退出。多线程程序在main()方法和所以非守护线程都返回时才退出。(守护线程会执行后台任务,如垃圾回收,并不阻止虚拟机退出)。
-------------
线程的2种实现方法
1、继承Thread类
2、实现Runable接口
一般推荐第二种方法,没有充分的理由。可以节约一个继承。
并在run()方法里面实现具体内容。
线程run()方法是固定的,所以无法向其传入参数或从中返回值。
传递参数:最简单的的方法是向构造函数传递参数。
返回参数:使用回调。
在线程类中,最后的位置,使用静态方法,或传过来的对象的实例方法回调。
同步
只要是多线程共享资源或代码,都必须考虑同步。
使用关键字synchronized来实现同步块或者同步方法。
同步的替代方法
对于线程调度引起的不一致行为问题,同步并不总是最好的解决方案。还有很多技术可以完全避免使用同步。
1、在任何可能的情况下,使用局部变量代替字段,局部变量没有同步问题。
java通过值而不是引用来传递参数。
String参数是安全的,因为它们是不可变的,final类型。StringBuffer参数是不安全的,因为它们不是不可变的,可以在创建后加以修改。
2、在自己的类中利用不可变性。要使一个对象不可变,只要将其所以字段声明为私有,不要编写任何可以改变它们的方法就行了。核心java库中有很多类是不可变的:如String,Integer等
3、只将非现场安全的类作用线程安全的类的一个私有字段。只要包含类仅以线程安全的方式访问此非安全类,并且只要永远不让这个私有字段的引用泄露到另一个对象中,那么这个类就是安全的。
死锁
同步会导致另一个可能的问题:死锁。
写完论文需要看图书馆A,B两本书。张去图书馆借了A书,想借B书发现被李借走了。李也要写论文,想借A书,发现被张借走了。此时他们互不相让,就发送死锁。
解决办法是:让程序顺序访问。既是借书,必须先借A再借B。
线程调度
优先级
java中,10是最高优先级,1是最低。默认为5.
设置优先级通过以下方法:
public final void setPriority(int newPriority)
在线程启动前调用:
t.setPriority(8);
t.start();
一般尽量使用太高优先级,避免其他线程遭受"饥饿"之苦。
分享到:
相关推荐
实验八线程1 实验八线程1是南方科技大学计算机操作系统实验课程的一部分,旨在加深对线程的理解,掌握多线程基本编程方法,多线程之间同步与互斥的方法。下面是实验八线程1的详细知识点: 1. 线程基本知识 线程是...
"多线程编程基础知识" 多线程编程是指在一个程序中同时执行多个线程的技术。每个线程都是一个独立的执行路径,拥有自己的程序计数器、寄存器和堆栈空间。多线程编程可以提高程序的执行效率和响应速度,但也增加了...
1. **线程同步**:在退出线程之前,确保该线程所占用的资源已经释放,且与其他线程之间的交互已完成。可以使用易语言提供的“等待”、“唤醒”等同步命令,确保线程安全地结束。 2. **避免强制终止**:尽量避免使用...
Console.WriteLine("线程1正在执行..."); } } ``` 在上述代码中,`WorkerMethod`是新线程将要执行的方法。`ThreadStart`委托指向这个方法,然后`thread1.Start()`启动了新线程。 除了手动创建线程,还可以使用`...
1. 初始化互斥锁:在程序开始时,我们需要创建一个互斥锁,确保在多线程环境下对图像数据的访问是安全的。 2. 创建处理线程:启动一个新的线程,该线程执行图像处理任务。处理过程中,线程会周期性地更新图像数据。 ...
thread1.setName("线程1"); thread2.setName("线程2"); thread1.start(); thread2.start(); } } ``` 在上述代码中,我们为每个线程设置了不同的名字,这样可以更容易地识别输出结果来自哪个线程。`start()`...
java多线程每个线程挨着打印ABC的4种实现方式,有4个线程t1、t2、t3、t4,t1打印A后t2打印A再t3打印A再t4打印A,然后从新回到t1打印B再t2打印B...t4打印B... 4个线程轮流打印abc... 一个线程可以理解为一个人,打印...
//线程1执行的函数//线程2执行的函数//创建线程id//创建线程p1 去执行 th1函数 (不带参数)//创建线程p2 去执行 th2函数 (带参数)//调
1. **核心级线程与用户级线程的不同** - **创建与销毁**:用户级线程由用户空间的线程库管理,创建和销毁不需要经过内核;而内核级线程由操作系统内核直接控制,创建和销毁涉及到内核态的上下文切换。 - **调度...
1. 前台线程:与进程生命周期绑定,只有所有前台线程都结束,进程才会终止。 2. 后台线程:不影响进程生命周期,即使所有后台线程仍在运行,进程也会结束。 七、线程池 线程池是一种线程复用机制,用于减少线程...
1. 使用`Thread`类:通过实例化`Thread`类并传递一个委托(如`ThreadStart`或`ParameterizedThreadStart`)来创建线程。例如: ```csharp Thread thread = new Thread(new ThreadStart(YourMethod)); thread.Start()...
1. **互斥量(Mutex)**:互斥量提供了一种独占访问资源的方式,同一时间只有一个线程可以持有互斥量并访问资源。在C++中,我们可以使用`std::mutex`来实现。当一个线程获得互斥锁后,其他尝试获取的线程将被阻塞,...
//线程1线程句柄 HANDLE hThread2; //线程2线程句柄 HANDLE hThread3; //线程3线程句柄 在增加三个结构体类型的变量,用做线程函数的参数传递; HANDLE hThread1; //线程1线程句柄 HANDLE hThread2; //线程2...
当我们需要在多线程环境中进行调试时,"3线程1和2都会断点.png"展示了可能出现的情况:在某一行设置断点后,所有通过该行的线程都会触发断点。这可能导致混乱,因为你可能只想暂停特定线程的执行。 IntelliJ IDEA...
线程是操作系统中的一种基本执行单元,它在程序执行中扮演着重要角色。在操作系统领域,线程的引入主要是为了实现并发性和资源分享。本文将深入探讨线程的概念,包括线程的定义、多线程进程的优势以及线程与进程的...
' 建立线程1 hThread = CreateThread(0&, 0&, AddressOf AsyncThread, 0&, 0&, hThreadID) CloseHandle hThread ' 建立线程2 hThread1 = CreateThread(0&, 0&, AddressOf AsyncThread1, 0&, 0&, hThreadID) ...
在实验中,我们创建了两个线程,线程 1 和线程 2。我们使用 SuspendThread 和 ResumeThread 函数来挂起和恢复线程,并使用 GetExitCodeThread 函数来获取线程的退出码。实验结果表明,多线程编程可以提高系统的并发...
1. 编写程序,使用两个线程,一个队列, 其中一个线程从键盘读取数据,放入到队列中,直到读取的数据是字符串quit则结束,线程的任务就是循环读取数据直到特定的字符串quit。另外一个线程,不断的从队列中读取数据...
例如,我们可以创建一个新线程并指定一个方法(即线程的入口点)来执行特定任务,如计算1到1百万的值。线程启动后,它将独立于主线程运行,直到完成指定的工作或者被中断。 2. **线程的暂停** 线程的暂停功能允许...