Java多线程与窗口创建编程指南
立即解锁
发布时间: 2025-08-18 02:26:29 阅读量: 2 订阅数: 17 

### Java 多线程与窗口创建编程指南
#### 1. 多线程编程基础
线程是程序中可以并发执行的子任务。在 Java 中,线程由 `Thread` 类的对象表示,线程的执行从 `Thread` 类中定义的 `run()` 方法开始。可以通过继承 `Thread` 类或实现 `Runnable` 接口来定义线程要执行的代码。
以下是线程编程的一些关键概念:
| 概念 | 描述 |
| ---- | ---- |
| 守护线程 | 指定为守护线程的线程在创建它的线程结束时停止执行。 |
| 用户线程 | 非守护线程称为用户线程,创建它的线程结束时,用户线程不会自动终止。 |
| 启动线程 | 可以通过调用 `Thread` 对象的 `start()` 方法来启动线程。如果需要在正常完成之前停止线程,可以调用 `Thread` 对象的 `interrupt()` 方法。 |
| 同步方法 | 方法可以声明为同步的。在任何给定时间,对象的同步实例方法只能有一个执行,类的同步静态方法也只能有一个执行。 |
| 同步代码块 | 代码块可以声明为在对象上同步。在任何给定时间,对象的同步代码块只能有一个执行。 |
| 死锁 | 死锁是指两个线程都在等待对方完成某个操作的情况。在多线程应用程序中,死锁可能以微妙的方式发生,这使得此类应用程序难以调试。 |
| 执行器 | 执行器是可以创建、管理和启动线程的对象。可以通过调用 `Executors` 类中定义的静态方法之一来创建执行器对象。 |
| 线程池 | 可以创建提供固定数量线程(可重用)或无限数量线程的执行器。 |
| 返回值的线程 | 返回值的线程由实现 `Callable<V>` 接口的类定义。该接口定义了返回类型为 `V` 的 `call()` 方法。 |
| `Future<V>` 对象 | `ExecutorService` 对象的 `submit()` 方法启动线程时会返回一个 `Future<V>` 对象。可以使用返回的对象管理线程并获取 `Callable<>` 线程的结果。 |
#### 2. 线程优先级
所有线程都有一个优先级,当多个线程等待执行时,优先级决定了哪个线程先执行。这使得可以让一个线程比另一个线程更多地访问处理器资源。
线程优先级的可能值在 `Thread` 类的静态数据成员中定义,这些成员是 `int` 类型且声明为 `final`。最大线程优先级由 `MAX_PRIORITY` 成员定义,值为 10;最小优先级是 `MIN_PRIORITY`,定义为 1;程序中主线程的默认优先级是 `NORM_PRIORITY`,设置为 5。创建线程时,其优先级与创建它的线程相同。
可以通过调用表示线程的 `Thread` 对象的 `setPriority()` 方法来修改线程的优先级。如果指定的优先级小于 `MIN_PRIORITY` 或大于 `MAX_PRIORITY`,则会抛出 `IllegalArgumentException`。
以下是一个设置线程优先级的示例:
```java
// 修改 Clerk 类构造函数以接受优先级参数
public Clerk(int ID, Bank theBank, int priority) {
this.ID = ID;
this.theBank = theBank;
this.priority = priority;
}
// 添加优先级成员变量
private int priority;
// 在 run() 方法中设置线程优先级
public void run() {
Thread.currentThread().setPriority(priority); // Set priority for thread
// 其他代码
}
// 修改 TransactionSource 类构造函数以接受优先级参数
public TransactionSource(TransactionType type, int maxTrans,
Vector<Account> accounts, Vector<Clerk> clerks, int priority) {
this.type = type;
this.maxTrans = maxTrans;
this.accounts = accounts;
this.clerks = clerks;
this.priority = priority;
totals = new int[accounts.size()];
}
// 添加优先级成员变量
private int priority;
// 在 call() 方法中设置线程优先级
public Integer call() throws Exception {
Thread.currentThread().setPriority(priority); // Set priority for thread
// 其他代码
}
// 在 main() 方法中设置线程优先级
int priority = 0;
for(int i = 0 ; i < clerkCount ; ++i) {
priority = i%2 == 0 ? Thread.MIN_PRIORITY + (i + 1) : Thread.MAX_PRIORITY - (i + 1);
if(priority < Thread.MIN_PRIORITY || priority > Thread.MAX_PRIORITY)
priority = Thread.NORM_PRIORITY;
clerks.add(new Clerk(i+1, theBank, priority)); // Create the clerks
}
```
#### 3. 多线程执行示例
在创建账户和职员后,可以通过调用 `Executors` 类的 `newCachedThreadPool()` 工厂方法获取一个执行器对象的 `ExecutorService` 引用:
```java
ExecutorService threadPool = Executors.newCachedThreadPool();
```
这个执行器可以根据需要提供任意数量的线程。可以在 `ExecutorService` 对象的 `submit()` 方法的参数中创建 `TransactionSource` 对象:
```java
Future<int[]> credits = threadPool.submit(new TransactionSource(
TransactionType.CREDIT, transactionCount, accounts, clerks));
Future<int[]> debits = threadPool.submit(new TransactionSource(
TransactionType.DEBIT, transactionCount, accounts, clerks));
```
只需要 `submit()` 方法返回的 `Future<>` 对象的引用,因为这些对象可以让你访问 `Callable<>` 线程返回的值以及控制其执行的方法。
接下来,在循环中创建并启动职员线程:
```java
for(Clerk clerk : clerks) {
threadPool.submit(clerk);
}
```
执行这个循环后,包括主线程在内,总共有五个线程在运行。
可以通过调用 `ExecutorService` 对象的 `submit()` 方法返回的 `Future<>` 对象的 `get()` 方法来检索 `TransactionSource` 线程返回的值。这在 `try` 块中进行,以处理可能抛出的异常。
在生成总结每个账户状态的最终输出之前,需要有序地关闭线程和线程池。首先调用 `threadPool` 对象的 `shutdown()` 方法,以确保不再有新线程
0
0
复制全文
相关推荐









