在这篇文章中,我们将通过实例学习重要的线程类API/方法。
类图显示了java.lang.Thread
类API/方法的列表。
让我们来演示一下 java.lang.Thread
类的几个重要方法的用法。
Thread.sleep使当前线程在指定的时间内暂停执行。这是一种有效的手段,可以让一个应用程序的其他线程或可能在计算机系统上运行的其他应用程序获得处理器时间。
Thread.sleep()方法实例
在这个例子中,我们创建并启动了两个线程thread1
和thread2
。请注意,我们在这个例子中使用了sleep()
方法的两个重载版本。
Thread.sleep(1000);
Thread.sleep(1000, 500);
/**
* thread sleep method examples
* @author Ramesh fadatare
*
*/
public class ThreadSleepExample {
public static void main(final String[] args) {
System.out.println("Thread main started");
final Thread thread1 = new Thread(new WorkerThread());
thread1.setName("WorkerThread 1");
final Thread thread2 = new Thread(new WorkerThread());
thread1.setName("WorkerThread 2");
thread1.start();
thread2.start();
System.out.println("Thread main ended");
}
}
class WorkerThread implements Runnable {
@Override
public void run() {
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(1000);
Thread.sleep(1000, 500);
System.out.println("[" + Thread.currentThread().getName() + "] Message " + i);
} catch (final InterruptedException e) {
e.printStackTrace();
}
}
}
}
输出。
Thread main started
Thread main ended
[WorkerThread 2] Message 0
[Thread-1] Message 0
[WorkerThread 2] Message 1
[Thread-1] Message 1
[WorkerThread 2] Message 2
[Thread-1] Message 2
[WorkerThread 2] Message 3
[Thread-1] Message 3
[WorkerThread 2] Message 4
[Thread-1] Message 4
注意,*sleep()*方法会抛出InterruptedException异常,当另一个线程在睡眠状态下中断了当前线程时。
join()方法会等待一个线程死亡。换句话说,它使当前运行的线程停止执行,直到它加入的线程完成其任务。
线程join()方法的例子。 我们将首先创建一个任务,它将计算1-5个数字的总和(在for循环中维护)。在主线程中,我们创建4个任务。
final Task task1 = new Task(500l);
final Task task2 = new Task(1000l);
final Task task3 = new Task(2000l);
final Task task4 = new Task(50l);
现在,让我们创建4个线程来运行上述4个任务。
final Thread thread1 = new Thread(task1);
final Thread thread2 = new Thread(task2);
final Thread thread3 = new Thread(task3);
final Thread thread4 = new Thread(task4);
为每个线程指定名称并启动所有4个线程。
thread1.setName("thread-1");
thread2.setName("thread-2");
thread3.setName("thread-3");
thread4.setName("thread-4");
thread1.start();
thread2.start();
thread3.start();
thread4.start();
在这个例子中,当目标线程完成求和时,调用者线程(main)醒来并调用*task.getSum()*方法,由于目标线程已经完成了它的工作,它肯定会包含总和。task4
的睡眠时间很小,因此它在其他线程之前完成了总和。因此,主线程调用thread4.join()
,但由于thread4
已经完成,所以立即返回其执行。
/**
* This class demonstrate the how join method works with an example.
* @author Ramesh Fadatare
*
*/
public class ThreadJoinExample {
public static void main(final String[] args) throws InterruptedException {
System.out.println("Thread main started");
final Task task1 = new Task(500l);
final Task task2 = new Task(1000l);
final Task task3 = new Task(2000l);
final Task task4 = new Task(50l);
final Thread thread1 = new Thread(task1);
final Thread thread2 = new Thread(task2);
final Thread thread3 = new Thread(task3);
final Thread thread4 = new Thread(task4);
thread1.setName("thread-1");
thread2.setName("thread-2");
thread3.setName("thread-3");
thread4.setName("thread-4");
thread1.start();
thread2.start();
thread3.start();
thread4.start();
System.out.println("[" + Thread.currentThread().getName() + "] waiting for " + thread1.getName());
thread1.join();
System.out.println(thread1.getName() + " finished! Result: " + task1.getSum());
System.out.println("[" + Thread.currentThread().getName() + "] waiting for " + thread2.getName());
thread2.join();
System.out.println(thread2.getName() + " finished! Result: " + task2.getSum());
System.out.println("[" + Thread.currentThread().getName() + "] waiting for " + thread3.getName());
thread3.join();
System.out.println(thread3.getName() + " finished! Result: " + task3.getSum());
// As thread-4 already finished (smaller sleep time), the join call only immediately
// returns the control to the caller thread
System.out.println("[" + Thread.currentThread().getName() + "] waiting for " + thread4.getName());
thread4.join();
System.out.println(thread4.getName() + " finished! Result: " + task4.getSum());
System.out.println("Thread main finished");
}
}
class Task implements Runnable {
private long sleep;
private int sum;
public Task(final long sleep) {
this.sleep = sleep;
}
@Override
public void run() {
for (int i = 1; i <= 5; i++) {
System.out.println("[" + Thread.currentThread().getName() + "] Adding " + i);
sum += i;
try {
Thread.sleep(sleep);
} catch (final InterruptedException e) {
e.printStackTrace();
}
}
}
public int getSum() {
return this.sum;
}
}
输出:
Thread main started
[thread-1] Adding 1
[thread-2] Adding 1
[thread-3] Adding 1
[main] waiting for thread-1
[thread-4] Adding 1
[thread-4] Adding 2
[thread-4] Adding 3
[thread-4] Adding 4
[thread-4] Adding 5
[thread-1] Adding 2
[thread-1] Adding 3
[thread-2] Adding 2
[thread-1] Adding 4
[thread-1] Adding 5
[thread-3] Adding 2
[thread-2] Adding 3
thread-1 finished! Result: 15
[main] waiting for thread-2
[thread-2] Adding 4
[thread-2] Adding 5
[thread-3] Adding 3
thread-2 finished! Result: 15
[main] waiting for thread-3
[thread-3] Adding 4
[thread-3] Adding 5
thread-3 finished! Result: 15
[main] waiting for thread-4
thread-4 finished! Result: 15
Thread main finished
注意,输出,main()线程最后完成了它的执行。试着通过观察一个输出来理解这个例子。join()
方法抛出一个InterruptedException
--如果有任何线程打断了当前线程。当这个异常被抛出时,当前线程的中断状态被清除了。
中断是对一个线程的指示,它应该停止它正在做的事情,做一些别的事情。线程对中断的具体响应方式由程序员决定,但线程终止是非常常见的。
java.lang线程类提供了三个interrupt()
方法来正确处理中断。
public class TerminateTaskUsingThreadAPI {
public static void main(final String[] args) {
System.out.println("Thread main started");
final Task task = new Task();
final Thread thread = new Thread(task);
thread.start();
thread.interrupt();
System.out.println("Thread main finished");
}
}
class Task implements Runnable {
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println("[" + Thread.currentThread().getName() + "] Message " + i);
if (Thread.interrupted()) {
System.out.println("This thread was interruped by someone calling this Thread.interrupt()");
System.out.println("Cancelling task running in thread " + Thread.currentThread().getName());
System.out.println("After Thread.interrupted() call, JVM reset the interrupted value to: " + Thread.interrupted());
break;
}
}
}
}
输出:
Thread main started
Thread main finished
[Thread-0] Message 0
This thread was interruped by someone calling this Thread.interrupt()
Cancelling task running in thread Thread-0
After Thread.interrupted() call, JVM reset the interrupted value to: false
注意,这里是任务被终止,而不是线程被终止。
java.lang.Thread类提供了*isAlive()*方法来测试这个线程是否活着。如果一个线程已经被启动并且还没有死亡,那么它就是活的。
Thread is isAlive方法示例
final Thread thread1 = new Thread(new MyTask());
final Thread thread2 = new Thread(new MyTask());
System.out.println("Thread1 is alive? " + thread1.isAlive());
System.out.println("Thread2 is alive? " + thread2.isAlive());
thread1.start();
thread2.start();
while (thread1.isAlive() || thread2.isAlive()) {
System.out.println("Thread1 is alive? " + thread1.isAlive());
System.out.println("Thread2 is alive? " + thread2.isAlive());
Thread.sleep(500l);
}
让我们把所有的东西放在一起,完整的程序。
public class CheckIfThreadIsAliveUsingThreadAPI {
public static void main(final String[] args) throws InterruptedException {
System.out.println("Thread main started");
final Thread thread1 = new Thread(new MyTask());
final Thread thread2 = new Thread(new MyTask());
System.out.println("Thread1 is alive? " + thread1.isAlive());
System.out.println("Thread2 is alive? " + thread2.isAlive());
thread1.start();
thread2.start();
while (thread1.isAlive() || thread2.isAlive()) {
System.out.println("Thread1 is alive? " + thread1.isAlive());
System.out.println("Thread2 is alive? " + thread2.isAlive());
Thread.sleep(500l);
}
System.out.println("Thread1 is alive? " + thread1.isAlive());
System.out.println("Thread2 is alive? " + thread2.isAlive());
System.out.println("Thread main finished");
}
}
class MyTask implements Runnable {
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println("[" + Thread.currentThread().getName() + "] Message " + i);
try {
Thread.sleep(200);
} catch (final InterruptedException e) {
e.printStackTrace();
}
}
}
}
输出。
Thread main started
Thread1 is alive? false
Thread2 is alive? false
Thread1 is alive? true
Thread2 is alive? true
[Thread-0] Message 0
[Thread-1] Message 0
[Thread-1] Message 1
[Thread-0] Message 1
[Thread-1] Message 2
[Thread-0] Message 2
Thread1 is alive? true
Thread2 is alive? true
[Thread-0] Message 3
[Thread-1] Message 3
[Thread-1] Message 4
[Thread-0] Message 4
Thread1 is alive? false
Thread2 is alive? false
Thread main finished
每个线程都有一个优先级。优先级用1到10之间的数字表示。在大多数情况下,线程调度器会根据线程的优先级来调度它们(称为抢占式调度)。但这并不保证,因为这取决于JVM的规范,它选择哪种调度方式。
在Thread类中定义了三个常量。
1.公共静态int MIN_PRIORITY
1.公共静态int NORM_PRIORITY
MAX_PRIORITY
线程的默认优先级是5(NORM_PRIORITY
)。MIN_PRIORITY
的值是1,MAX_PRIORITY
的值是10。
public class ThreadPriorityExample {
public static void main(final String[] args) {
final Runnable runnable = () -> {
System.out.println("Running thread name : " + Thread.currentThread().getName() +
" and it's priority : " + Thread.currentThread().getPriority());
};
final Thread thread1 = new Thread(runnable);
final Thread thread2 = new Thread(runnable);
final Thread thread3 = new Thread(runnable);
final Thread thread4 = new Thread(runnable);
thread1.setPriority(Thread.MIN_PRIORITY);
thread2.setPriority(Thread.NORM_PRIORITY);
thread3.setPriority(Thread.MAX_PRIORITY);
thread4.setPriority(2);
thread1.start();
thread2.start();
thread3.start();
thread4.start();
}
}
输出:
Running thread name : Thread-0 and it's priority : 1
Running thread name : Thread-1 and it's priority : 5
Running thread name : Thread-2 and it's priority : 10
Running thread name : Thread-3 and it's priority : 2
java.lang.Thread
类提供了改变和获得线程名称的方法。默认情况下,每个线程都有一个名字,即thread-0, thread-1
等等。通过使用setName()
方法,我们可以改变线程的名称。setName() and getName()
方法的语法如下。
public String getName()
: 用于返回线程的名称。public void setName(String name):
用于改变一个线程的名称。命名一个线程的例子
/**
* Thread naming example using Thread class.
* @author Ramesh fadatare
**/
public class ThreadExample {
public static void main(final String[] args) {
System.out.println("Thread main started");
final Thread thread1 = new WorkerThread();
thread1.setName("WorkerThread1");
final Thread thread2 = new WorkerThread();
thread2.setName("WorkerThread2");
final Thread thread3 = new WorkerThread();
thread3.setName("WorkerThread3");
final Thread thread4 = new WorkerThread();
thread4.setName("WorkerThread4");
thread1.start();
thread2.start();
thread3.start();
thread4.start();
System.out.println("Thread main finished");
}
}
class WorkerThread extends Thread {
@Override
public void run() {
System.out.println("Thread Name :: " + Thread.currentThread().getName());
}
}
输出
Thread main started
Thread Name :: WorkerThread1
Thread Name :: WorkerThread2
Thread Name :: WorkerThread3
Thread main finished
Thread Name :: WorkerThread4
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://www.javaguides.net/2018/10/thread-class-methods-in-java-with-examples.html
内容来源于网络,如有侵权,请联系作者删除!