📅  最后修改于: 2023-12-03 15:02:04.585000             🧑  作者: Mango
Java中的多线程是实现程序并发的一种方法,它可以使程序在同一时间内执行多个任务。但是,当多个线程共享相同的资源时,就可能会导致冲突和不一致的结果。因此,开发者需要了解如何使用Java并发库来确保线程安全。
Java中提供了一些方法来处理线程之间的协作。yield()、sleep() 和 join() 是这些方法中最常用的三种。这篇文章将会介绍这三种方法及其用法。
yield() 方法是一个静态方法,该方法会使当前正在执行的线程暂停并允许其他可运行线程执行。这个方法的作用是向调度程序提示当前线程愿意让出 CPU 执行时间,但是并不能保证一定会让出 CPU 资源,也不能保证让出的 CPU 资源会被其他线程立即执行。
下面是一个使用 yield() 方法的示例代码:
public class YieldExample implements Runnable {
String name;
YieldExample(String name) {
this.name = name;
}
public void run() {
for (int i = 0; i < 5; i++) {
// Yield control to another thread
Thread.yield();
System.out.println(name + " running");
}
}
public static void main(String[] args) {
Thread t1 = new Thread(new YieldExample("Thread 1"));
Thread t2 = new Thread(new YieldExample("Thread 2"));
t1.start();
t2.start();
}
输出结果:
Thread 1 running
Thread 2 running
Thread 1 running
Thread 2 running
Thread 1 running
Thread 2 running
Thread 1 running
Thread 2 running
Thread 1 running
Thread 2 running
由于使用了 yield() 方法,两个线程轮流执行了5次,而不是一个线程执行完毕后另一个线程再执行。
需要注意的是,yield() 方法不应该被滥用。如果过度使用,它可能会导致 CPU 的利用率减少。
sleep() 方法会使当前线程暂停执行指定的时间。该方法的一个常见用途是模拟线程之间的时间间隔,通常结合其他方法使用来使程序的执行更具可控性。
下面是一个使用 sleep() 方法的示例代码:
public class SleepExample implements Runnable {
String name, message;
SleepExample(String name, String message) {
this.name = name;
this.message = message;
}
public void run() {
try {
for (int i = 0; i < 5; i++) {
System.out.println(name + " : " + message);
Thread.sleep(1000); // sleep for 1 second
}
} catch (InterruptedException e) {}
}
public static void main(String[] args) {
Thread t1 = new Thread(new SleepExample("Thread 1", "Hello"));
Thread t2 = new Thread(new SleepExample("Thread 2", "World"));
t1.start();
t2.start();
}
}
输出结果:
Thread 1 : Hello
Thread 2 : World
Thread 1 : Hello
Thread 2 : World
Thread 1 : Hello
Thread 2 : World
Thread 1 : Hello
Thread 2 : World
Thread 1 : Hello
Thread 2 : World
在这个例子中,每个线程将执行5次打印操作,在两次打印之间暂停1秒钟。
在使用 sleep() 方法时,需要注意它可能会抛出 InterruptedException 异常,因此需要进行适当的异常处理。
join() 方法用于等待一个线程的执行完成。该方法会阻塞调用 join() 方法的线程,直到被等待的线程执行完成。
下面是一个使用 join() 方法的示例代码:
public class JoinExample implements Runnable {
String name;
JoinExample(String name) {
this.name = name;
}
public void run() {
try {
for (int i = 0; i < 5; i++) {
System.out.println(name + " running");
Thread.sleep(1000); // sleep for 1 second
}
} catch (InterruptedException e) {}
}
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(new JoinExample("Thread 1"));
Thread t2 = new Thread(new JoinExample("Thread 2"));
t1.start();
// Wait for t1 to finish
t1.join();
t2.start();
}
}
输出结果:
Thread 1 running
Thread 1 running
Thread 1 running
Thread 1 running
Thread 1 running
Thread 2 running
Thread 2 running
Thread 2 running
Thread 2 running
Thread 2 running
在这个例子中,线程 t2 在执行之前需要等待线程 t1 执行完成。调用 t1.join() 方法使得主线程等待 t1 的执行完成后,才开始启动 t2 线程。
需要注意的是,join() 方法被调用时可以指定等待的时间,例如 t1.join(5000); 会等待 t1 执行完成或过了 5000 毫秒后才会执行后面的代码。如果不指定等待时间,默认会一直等待线程执行完毕。
yield()、sleep() 和 join() 都是 Java 并发库提供的非常有用的方法。使用它们可以帮助我们更好地控制线程的执行,避免冲突和不一致的结果。需要注意的是,这些方法都不是万能的,过度使用它们可能会导致性能下降或其他不良后果。因此,使用它们时需要谨慎。