Java多线程编程:线程优先级、同步机制与对象锁详解
立即解锁
发布时间: 2025-08-18 00:08:23 阅读量: 2 订阅数: 9 

# Java 多线程编程:线程优先级、同步机制与对象锁详解
## 1. 线程优先级与 `yield` 方法
在 Java 中,线程优先级是一个重要的概念。`Thread` 类提供了设置线程优先级的方法 `setPriority(int newPriority)`,优先级必须在 `Thread.MIN_PRIORITY`(值为 1)和 `Thread.MAX_PRIORITY`(值为 10)之间,通常使用 `Thread.NORM_PRIORITY`(值为 5)作为默认优先级。
`yield()` 方法是一个静态方法,它会使当前执行的线程让出 CPU 资源。如果有其他可运行的线程,且它们的优先级至少和当前线程相同,那么这些线程将被调度执行。
### 1.1 自私线程示例
在某些情况下,线程可能会表现得很“自私”。例如,当一个线程包含一个紧密循环,在循环中执行大量工作而不给其他线程机会时,就会出现这种情况。以下是一个示例代码:
```java
class BallThread extends Thread {
// ...
public void run() {
try {
for (int i = 1; i <= 1000; i++) {
b.move();
if (selfish) {
// busy wait for 5 milliseconds
long t = System.currentTimeMillis();
while (System.currentTimeMillis() < t + 5)
;
} else
sleep(5);
}
} catch (InterruptedException exception) {
}
}
// ...
private boolean selfish;
}
```
当 `selfish` 标志被设置时,`run` 方法会持续大约五秒,期间不会调用 `sleep` 或 `yield` 方法。运行这个程序的实际效果取决于操作系统和线程实现方式。在 Solaris 或 Linux 上使用“绿色线程”实现时,自私的线程可能会独占整个应用程序;而在 Windows 或使用“本地线程”实现时,蓝色球可以与其他球并行运行。
### 1.2 建议
为了避免线程独占系统资源,当线程执行长循环时,应该调用 `sleep` 或 `yield` 方法。这样可以确保线程不会垄断系统资源,让其他线程有机会执行。
## 2. 线程同步机制
在多线程应用程序中,多个线程可能需要共享对同一对象的访问。如果两个线程同时访问同一个对象并调用修改对象状态的方法,可能会导致数据不一致的问题,这种情况被称为竞态条件。
### 2.1 无同步的线程通信示例
以下是一个模拟银行转账的示例,有 10 个账户和 10 个线程,每个线程负责一个账户的转账操作:
```java
public class UnsynchBankTest {
public static void main(String[] args) {
Bank b = new Bank(NACCOUNTS, INITIAL_BALANCE);
int i;
for (i = 0; i < NACCOUNTS; i++) {
TransferThread t = new TransferThread(b, i, INITIAL_BALANCE);
t.setPriority(Thread.NORM_PRIORITY + i % 2);
t.start();
}
}
public static final int NACCOUNTS = 10;
public static final int INITIAL_BALANCE = 10000;
}
class Bank {
public Bank(int n, int initialBalance) {
accounts = new int[n];
int i;
for (i = 0; i < accounts.length; i++)
accounts[i] = initialBalance;
ntransacts = 0;
}
public void transfer(int from, int to, int amount) throws InterruptedException {
if (accounts[from] < amount) return;
accounts[from] -= amount;
accounts[to] += amount;
ntransacts++;
if (ntransacts % NTEST == 0) test();
}
public void test() {
int sum = 0;
for (int i = 0; i < accounts.length; i++)
sum += accounts[i];
System.out.println("Transactions:" + ntransacts + " Sum: " + sum);
}
public int size() {
return accounts.length;
}
pu
```
0
0
复制全文
相关推荐










