1. 什么是线程
传统的程序设计语言同一时刻只能执行单任务操作,效率非常低,如果网络程序在接收数据时发生阻塞,只能等到程序接收数据之后才能继续运行。随着 Internet 的飞速发展,这种单任务运行的状况越来越不被接受。如果网络接收数据阻塞,后台服务程序就会一直处于等待状态而不能继续任何操作。这种阻塞情况经常发生,这时的 CPU资源完全处于闲置状态。
多线程实现后台服务程序可以同时处理多个任务,并不发生阻塞现象。多线程是 Java 语言的一个很重要的特征。多线程程序设计最大的特点就是能够提高程序执行效率和处理速度。Java 程序可同时并行运行多个相对独立的线程。例如创建一个线程来接收数据,另一个线程发送数据,既使发送线程在接收数据时被阻塞,接受数据线程仍然可以运行。 线程(Thread)是控制线程(Thread of Control)的缩写,它是具有一定顺序的指令序列(即所编写的程序代码)、存放方法中定义局部变量的栈和一些共享数据。线程是相互独立的,每个方法的局部变量和其他线程的局部变量是分开的,因此,任何线程都不能访问除自身之外的其他线程的局部变量。如果两个线程同时访问同一个方法,那每个线程将各自得到此方法的一个拷贝。
Java 提供的多线程机制使一个程序可同时执行多个任务。线程有时也被称为小进程,它是从一个大进程里分离出来的小的独立的线程。由于实现了多线程技术,Java 显得更健壮。多线程带来的好处是更好的交互性能和实时控制性能。多线程是强大而灵巧的编程工具,但要用好它却不是件容易的事。在多线程编程中,每个线程都通过代码实现线程的行为,并将数据供给代码操作。编码和数据有时是相当独立的,可分别向线程提供。多个线程可以同时处理同一代码和同一数据,不同的线程也可以处理各自不同的编码和数据。
2 .创建线程方法
Java程序都是声明一个公共类,并在类内实现一个 main 方法。事实上,这些程序就是一个单线程程序。当它执行完main 方法的程序后,线程正好退出,程序同时结束运行。
public class OnlyThread {
public static void main(String args[]) {
run(); // 调用静态run()方法
}
/**
* 实现run()方法
*/
public static void run() {
// 循环计算输出的*数目
for (int count = 1, row = 1; row < 10; row++, count++) {
for (int i = 0; i < count; i++) { // 循环输出指定的count数目的*
System.out.print('*');
}
System.out.println();
}
}
}
这只是建立了一个单一线程并执行的普通小程序,并没有涉及到多线程的概念。
在 Java程序中,有两种方法创建线程:
一是对 Thread 类进行派生并覆盖 run方法;
二是通过实现 runnable接口创建。
3. Thread 创建线程
在程序中创建新的线程的方法之一是继承 Thread 类,并通过 Thread子类声明线程对象。继承Thread 类并覆盖 Thread类的 run 方法完成线程类的声明,通过new创建派生线程类的线程对象。run 中的代码实现了线程的行为。
java.lang.Thread 类是一个通用的线程类,由于默认情况下 run 方法是空的,直接通过 Thread类实例化的线程对象不能完成任何事,所以可以通过派生 Thread 类,并用具体程序代码覆盖Thread 类中的 run 方法,实现具有各种不同功能的线程类。
1) Thread 创建线程步骤:
(1)创建一个新的线程类,继承 Thread 类并覆盖 Thread 类的 run()方法。
class ThreadType extends Thread{
public void run(){
……
}
}
(2)创建一个线程类的对象,创建方法与一般对象的创建相同,使用关键字new完成。
ThreadType tt = new ThreadType();
(3)启动新线程对象,调用 start()方法。
tt.start();
(4)线程自己调用 run()方法。
void run();
2) Thread创建一个线程
class ThreadDemo1 extends Thread {
ThreadDemo1() {
}
// 声明ThreadDemo1带参数的构造方法
ThreadDemo1(String szName) {
super(szName);
}
// 重载run函数
public void run() {
for (int count = 1, row = 1; row < 10; row++, count++) {
for (int i = 0; i < count; i++) {// 循环输出指定的count数目的*
System.out.print('*');
}
System.out.println();
}
}
public static void main(String argv[]) {
ThreadDemo1 td = new ThreadDemo1(); // 创建,并初始化ThreadDemo1类型对象td
td.start(); // 调用start()方法执行一个新的线程
}
}
OnlyThread.java程序与程序ThreadDemo1.java表面上看运行结果相同,但是仔细对照会发现,程序OnlyThread.java中对 run方法的调用在程序ThreadDemo1.java中变成了对 start 方法的调用,并且程序ThreadDemo1.java确派生 Thread类,创建新的线程类。
3) Thread创建多个线程
//产生三个新的线程
<!--[if !supportLineBreakNewLine]-->
<!--[endif]-->
public class ThreadDemo2 extends Thread {
// 声明无参数,空构造方法
ThreadDemo2() {
}
// 声明带有字符串参数的构造方法
ThreadDemo2(String szName) {
super(szName); // 调用父类的构造方法
}
// 重载run函数
public void run() {
for (int count = 1, row = 1; row < 10; row++, count++) {
for (int i = 0; i < count; i++) {// 循环输出指定的count数目的*
System.out.print('*');
}
System.out.println();
}
}
public static void main(String argv[]) {
ThreadDemo2 td1 = new ThreadDemo2(); // 创建,并初始化ThreadDemo2类型对象td1
ThreadDemo2 td2 = new ThreadDemo2(); // 创建,并初始化ThreadDemo2类型对象td2
ThreadDemo2 td3 = new ThreadDemo2(); // 创建,并初始化ThreadDemo2类型对象td3
td1.start(); // 启动线程td1
td2.start(); // 启动线程td2
td3.start(); // 启动线程td3
}
}
创建了 3 个线程 td1、td2、td3,它们分别执行自己的 run方法。在实际中运行的结果并不是想要的直角三角形,而是一些乱七八糟的 “*” 行,长短并没有一定的规律,这是因为线程并没有按照程序中调用的顺序来执行,而是产生了多个线程赛跑现象。 运行结果:
注意:Java线程并不能按调用顺序执行,而是并行执行的单独代码。如果要想得到完整的直角三角形,需要在执行一个线程之前,判断程序前面的线程是否终止,如果已经终止,再来调用该线程。
4. Runnable 接口创建线程
通过实现 Runnable 接口的方法是创建线程类的第二种方法。利用实现 Runnable 接口来创建线程的方法可以解决 Java 语言不支持的多重继承问题。 Runnable 接口提供了 run()方法的原型,因此创建新的线程类时,只要实现此接口,即只要特定的程序代码实现Runnable接口中的 run()方法,就可完成新线程类的运行。
扩展Thread类创建线程的方式,适合编写简单的应用程序代码,而实现Runnable接口创建线程,能够避免Java单继承的局限,适合同一代码的多线程处理同一资源的情况,代码具有良好的一致性,是更符合面向对象思想的设计方式。
1) Runnable 创建线程步骤
(1)创建一个实现 Runnable 接口的类,并且在这个类中重写 run 方法。
class ThreadType implements Runnable{
public void run(){
……
}
}
(2)使用关键字 new新建一个 ThreadType 的实例。
Runnable rb = new ThreadType ();
(3)通过 Runnable 的实例创建一个线程对象,在创建线程对象时,调用的构造函数是new Thread(ThreadType),它用 ThreadType 中实现的 run()方法作为新线程对象的 run()方法。
Thread td = new Thread(rb);
(4)通过调用 ThreadType 对象的 start()方法启动线程运行。
td.start();
2) Runnable 创建线程
class ThreadDemo3 implements Runnable {
// 重载run函数
public void run() {
for (int count = 1, row = 1; row < 10; row++, count++){ // 循环计算输出的*数目
for (int i = 0; i < count; i++){ // 循环输出指定的count数目的*
System.out.print('*');
}
System.out.println();
}
}
public static void main(String argv[]) {
Runnable rb = new ThreadDemo3(); // 创建,并初始化ThreadDemo3对象rb
Thread td = new Thread(rb); // 通过Thread创建线程
td.start(); // 启动线程td
}
}
相关推荐
易语言源码易语言线程上下文注入源码.rar 易语言源码易语言线程上下文注入源码.rar 易语言源码易语言线程上下文注入源码.rar 易语言源码易语言线程上下文注入源码.rar 易语言源码易语言线程上下文注入源码.rar ...
在这个示例中,`LongRunningOperation`方法在后台线程上执行,而`btnStart_Click`方法则继续执行,不会阻塞UI。`Invoke`方法确保在UI线程上安全地更新进度条。 通过正确使用异步编程,我们可以创建出既高效又用户...
在C#中,由于使用线程和调用UI的线程属于两个不同的线程,如果在线程中直接设置UI元素的属性,此时就会出现跨线程错误。 下面介绍两种解决方案 第一种:使用控件自带的Invoke或者BeginInvoke方法。 Task....
PLINQ能够自动地将查询操作分解到多个线程上执行,从而提高查询效率。 #### 八、计时器与锁 - **计时器**:`System.Threading.Timer` 类可用于实现定时任务。与`System.Timers.Timer`不同的是,前者更加高效且适合...
16丨多线程调优(下):如何优化多线程上下文切换?.html
多线程允许一个应用程序同时执行多个任务,每个任务都在一个独立的线程上运行。C#中,我们可以通过System.Threading命名空间下的类来创建和管理线程。主线程是应用程序启动时默认创建的,而额外的线程可以由开发者...
一种常见的方式是创建一个新的窗口类,该窗口类在不同的线程上运行。通过调用如CreateThread或BeginThread等API函数,可以在新的线程上下文中启动这个窗口类。同时,需要处理线程同步问题,例如使用Mutex、Semaphore...
在多线程环境中,事件处理通常在引发事件的线程上运行,因此,如果一个线程修改了UI控件的状态,而另一个线程尝试处理相关事件,可能会导致线程不安全。使用适当的同步机制可以解决这个问题。 "资源管理器"可能涉及...
为了确保UI的响应性,所有对UI的操作应在这个线程上进行。 9.6 线程同步: 线程同步是解决多线程环境下数据安全问题的关键。Java提供了synchronized关键字来实现方法或代码块的同步,防止多个线程同时访问同一块...
- `Control.Invoke`:用于在UI线程上执行指定的委托。如果当前线程是UI线程,方法会立即执行;否则,它会在UI线程的的消息队列中排队,等待执行。 - `Control.BeginInvoke`:异步版本的Invoke,它会将方法调用放入...
1. **BackgroundWorker组件**:这是.NET Framework提供的一种简单易用的多线程解决方案,适合在UI线程中启动,并在工作线程上执行任务。BackgroundWorker提供了ProgressChanged和RunWorkerCompleted事件,可以在UI...
而在多线程程序中,不同任务可以在不同的线程上并行运行。 要实现在VB6中创建线程,我们需要了解和使用以下API函数: 1. **CreateThread**:这是Windows API中的一个函数,用于创建新的线程。它的原型为: ```vb ...
在这里,`MyThreadFunction`是你定义的函数,它将在新线程上执行。 2. **线程同步与互斥**:在多线程环境中,线程同步是必要的,以防止多个线程同时访问共享资源,可能导致数据不一致。VB提供了`Mutex`类来实现...
这样,每一个控件或对象都会在自己的线程上运行,实现真正的多线程。 3. 编写线程代码 在ActiveX EXE工程中编写线程要执行的代码。通常,我们会创建一个类模块(Class Module),然后在这个类模块中定义线程函数,...
最后,`BackgroundWorker`组件提供了一种在后台线程上执行耗时操作的方式,同时允许在UI线程上更新进度和处理结果,这对于GUI应用特别有用。 综上所述,"大漠的c#多线程模板"应该包含了如何创建线程、使用线程池、...
1. **后台线程与主线程**:主线程是负责处理UI事件的线程,任何对UI的操作必须在这个线程上执行。后台线程则用于处理非UI相关的工作,如大数据计算、网络请求等,以避免阻塞主线程。 2. **Dispatcher对象**:每个...
这两个方法会确保在正确的线程上下文中执行操作。例如: ```csharp if (this.InvokeRequired) { this.Invoke(new Action(() => { // 在这里修改UI元素 textBox.Text = "新文本"; })); } else { // 直接...
它们不会影响用户界面的响应性,因为它们不在UI线程上运行。通过`AfxBeginThread`创建的工作线程,可以避免长时间计算导致的UI冻结。 3. **多线程编程** 多线程编程允许应用程序同时执行多个任务,提高资源利用率...
在多线程中,每个XMLHTTP对象可以在不同线程上独立工作。 3. **线程同步**:虽然多线程提高了并发性,但也会引入数据竞争问题。在VB6中,可能使用`Mutex`(互斥量)或`CriticalSection`来确保在特定时刻只有一个...
当我们需要在后台线程更新UI时,可以调用`Dispatcher.Invoke`或`Dispatcher.BeginInvoke`,这两个方法会确保操作在UI线程上执行。例如: ```csharp Application.Current.Dispatcher.Invoke(new Action(() => { // ...