Java中的线程类方法及示例

x33g5p2x  于2022-10-07 转载在 Java  
字(10.4k)|赞(0)|评价(0)|浏览(650)

在这篇文章中,我们将通过实例学习重要的线程类API/方法。

列出线程类的方法

类图显示了java.lang.Thread类API/方法的列表。

线程类方法与实例

让我们来演示一下 java.lang.Thread类的几个重要方法的用法。

Thread.sleep()方法

Thread.sleep使当前线程在指定的时间内暂停执行。这是一种有效的手段,可以让一个应用程序的其他线程或可能在计算机系统上运行的其他应用程序获得处理器时间。

Thread.sleep()方法实例
在这个例子中,我们创建并启动了两个线程thread1thread2。请注意,我们在这个例子中使用了sleep()方法的两个重载版本。

  1. Thread.sleep(1000);
  2. Thread.sleep(1000, 500);
  1. /**
  2. * thread sleep method examples
  3. * @author Ramesh fadatare
  4. *
  5. */
  6. public class ThreadSleepExample {
  7. public static void main(final String[] args) {
  8. System.out.println("Thread main started");
  9. final Thread thread1 = new Thread(new WorkerThread());
  10. thread1.setName("WorkerThread 1");
  11. final Thread thread2 = new Thread(new WorkerThread());
  12. thread1.setName("WorkerThread 2");
  13. thread1.start();
  14. thread2.start();
  15. System.out.println("Thread main ended");
  16. }
  17. }
  18. class WorkerThread implements Runnable {
  19. @Override
  20. public void run() {
  21. for (int i = 0; i < 5; i++) {
  22. try {
  23. Thread.sleep(1000);
  24. Thread.sleep(1000, 500);
  25. System.out.println("[" + Thread.currentThread().getName() + "] Message " + i);
  26. } catch (final InterruptedException e) {
  27. e.printStackTrace();
  28. }
  29. }
  30. }
  31. }

输出。

  1. Thread main started
  2. Thread main ended
  3. [WorkerThread 2] Message 0
  4. [Thread-1] Message 0
  5. [WorkerThread 2] Message 1
  6. [Thread-1] Message 1
  7. [WorkerThread 2] Message 2
  8. [Thread-1] Message 2
  9. [WorkerThread 2] Message 3
  10. [Thread-1] Message 3
  11. [WorkerThread 2] Message 4
  12. [Thread-1] Message 4

注意,*sleep()*方法会抛出InterruptedException异常,当另一个线程在睡眠状态下中断了当前线程时。

Thread.join()方法

join()方法会等待一个线程死亡。换句话说,它使当前运行的线程停止执行,直到它加入的线程完成其任务。

线程join()方法的例子。 我们将首先创建一个任务,它将计算1-5个数字的总和(在for循环中维护)。在主线程中,我们创建4个任务。

  1. final Task task1 = new Task(500l);
  2. final Task task2 = new Task(1000l);
  3. final Task task3 = new Task(2000l);
  4. final Task task4 = new Task(50l);

现在,让我们创建4个线程来运行上述4个任务。

  1. final Thread thread1 = new Thread(task1);
  2. final Thread thread2 = new Thread(task2);
  3. final Thread thread3 = new Thread(task3);
  4. final Thread thread4 = new Thread(task4);

为每个线程指定名称并启动所有4个线程。

  1. thread1.setName("thread-1");
  2. thread2.setName("thread-2");
  3. thread3.setName("thread-3");
  4. thread4.setName("thread-4");
  5. thread1.start();
  6. thread2.start();
  7. thread3.start();
  8. thread4.start();

在这个例子中,当目标线程完成求和时,调用者线程(main)醒来并调用*task.getSum()*方法,由于目标线程已经完成了它的工作,它肯定会包含总和。
task4的睡眠时间很小,因此它在其他线程之前完成了总和。因此,主线程调用thread4.join(),但由于thread4已经完成,所以立即返回其执行。

  1. /**
  2. * This class demonstrate the how join method works with an example.
  3. * @author Ramesh Fadatare
  4. *
  5. */
  6. public class ThreadJoinExample {
  7. public static void main(final String[] args) throws InterruptedException {
  8. System.out.println("Thread main started");
  9. final Task task1 = new Task(500l);
  10. final Task task2 = new Task(1000l);
  11. final Task task3 = new Task(2000l);
  12. final Task task4 = new Task(50l);
  13. final Thread thread1 = new Thread(task1);
  14. final Thread thread2 = new Thread(task2);
  15. final Thread thread3 = new Thread(task3);
  16. final Thread thread4 = new Thread(task4);
  17. thread1.setName("thread-1");
  18. thread2.setName("thread-2");
  19. thread3.setName("thread-3");
  20. thread4.setName("thread-4");
  21. thread1.start();
  22. thread2.start();
  23. thread3.start();
  24. thread4.start();
  25. System.out.println("[" + Thread.currentThread().getName() + "] waiting for " + thread1.getName());
  26. thread1.join();
  27. System.out.println(thread1.getName() + " finished! Result: " + task1.getSum());
  28. System.out.println("[" + Thread.currentThread().getName() + "] waiting for " + thread2.getName());
  29. thread2.join();
  30. System.out.println(thread2.getName() + " finished! Result: " + task2.getSum());
  31. System.out.println("[" + Thread.currentThread().getName() + "] waiting for " + thread3.getName());
  32. thread3.join();
  33. System.out.println(thread3.getName() + " finished! Result: " + task3.getSum());
  34. // As thread-4 already finished (smaller sleep time), the join call only immediately
  35. // returns the control to the caller thread
  36. System.out.println("[" + Thread.currentThread().getName() + "] waiting for " + thread4.getName());
  37. thread4.join();
  38. System.out.println(thread4.getName() + " finished! Result: " + task4.getSum());
  39. System.out.println("Thread main finished");
  40. }
  41. }
  42. class Task implements Runnable {
  43. private long sleep;
  44. private int sum;
  45. public Task(final long sleep) {
  46. this.sleep = sleep;
  47. }
  48. @Override
  49. public void run() {
  50. for (int i = 1; i <= 5; i++) {
  51. System.out.println("[" + Thread.currentThread().getName() + "] Adding " + i);
  52. sum += i;
  53. try {
  54. Thread.sleep(sleep);
  55. } catch (final InterruptedException e) {
  56. e.printStackTrace();
  57. }
  58. }
  59. }
  60. public int getSum() {
  61. return this.sum;
  62. }
  63. }

输出:

  1. Thread main started
  2. [thread-1] Adding 1
  3. [thread-2] Adding 1
  4. [thread-3] Adding 1
  5. [main] waiting for thread-1
  6. [thread-4] Adding 1
  7. [thread-4] Adding 2
  8. [thread-4] Adding 3
  9. [thread-4] Adding 4
  10. [thread-4] Adding 5
  11. [thread-1] Adding 2
  12. [thread-1] Adding 3
  13. [thread-2] Adding 2
  14. [thread-1] Adding 4
  15. [thread-1] Adding 5
  16. [thread-3] Adding 2
  17. [thread-2] Adding 3
  18. thread-1 finished! Result: 15
  19. [main] waiting for thread-2
  20. [thread-2] Adding 4
  21. [thread-2] Adding 5
  22. [thread-3] Adding 3
  23. thread-2 finished! Result: 15
  24. [main] waiting for thread-3
  25. [thread-3] Adding 4
  26. [thread-3] Adding 5
  27. thread-3 finished! Result: 15
  28. [main] waiting for thread-4
  29. thread-4 finished! Result: 15
  30. Thread main finished

注意,输出,main()线程最后完成了它的执行。试着通过观察一个输出来理解这个例子。
join()方法抛出一个InterruptedException--如果有任何线程打断了当前线程。当这个异常被抛出时,当前线程的中断状态被清除了。

Thread.interrupt()方法

中断是对一个线程的指示,它应该停止它正在做的事情,做一些别的事情。线程对中断的具体响应方式由程序员决定,但线程终止是非常常见的。

java.lang线程类提供了三个interrupt()方法来正确处理中断。

  1. void interrupt() - 中断这个线程。
  2. static boolean interrupted() - 测试当前线程是否已被中断。
  3. boolean isInterrupted() - 测试这个线程是否被中断。
    Thread.interrupt()方法示例
  1. public class TerminateTaskUsingThreadAPI {
  2. public static void main(final String[] args) {
  3. System.out.println("Thread main started");
  4. final Task task = new Task();
  5. final Thread thread = new Thread(task);
  6. thread.start();
  7. thread.interrupt();
  8. System.out.println("Thread main finished");
  9. }
  10. }
  11. class Task implements Runnable {
  12. @Override
  13. public void run() {
  14. for (int i = 0; i < 5; i++) {
  15. System.out.println("[" + Thread.currentThread().getName() + "] Message " + i);
  16. if (Thread.interrupted()) {
  17. System.out.println("This thread was interruped by someone calling this Thread.interrupt()");
  18. System.out.println("Cancelling task running in thread " + Thread.currentThread().getName());
  19. System.out.println("After Thread.interrupted() call, JVM reset the interrupted value to: " + Thread.interrupted());
  20. break;
  21. }
  22. }
  23. }
  24. }

输出:

  1. Thread main started
  2. Thread main finished
  3. [Thread-0] Message 0
  4. This thread was interruped by someone calling this Thread.interrupt()
  5. Cancelling task running in thread Thread-0
  6. After Thread.interrupted() call, JVM reset the interrupted value to: false

注意,这里是任务被终止,而不是线程被终止。

Thread.isAlive()方法

java.lang.Thread类提供了*isAlive()*方法来测试这个线程是否活着。如果一个线程已经被启动并且还没有死亡,那么它就是活的。

Thread is isAlive方法示例

  1. 让我们创建两个线程
  1. final Thread thread1 = new Thread(new MyTask());
  2. final Thread thread2 = new Thread(new MyTask());
  1. 在用start()方法启动线程之前,只需打印检查线程是否活着。
  1. System.out.println("Thread1 is alive? " + thread1.isAlive());
  2. System.out.println("Thread2 is alive? " + thread2.isAlive());
  1. 启动线程并再次检查线程是否存活
  1. thread1.start();
  2. thread2.start();
  3. while (thread1.isAlive() || thread2.isAlive()) {
  4. System.out.println("Thread1 is alive? " + thread1.isAlive());
  5. System.out.println("Thread2 is alive? " + thread2.isAlive());
  6. Thread.sleep(500l);
  7. }

让我们把所有的东西放在一起,完整的程序。

  1. public class CheckIfThreadIsAliveUsingThreadAPI {
  2. public static void main(final String[] args) throws InterruptedException {
  3. System.out.println("Thread main started");
  4. final Thread thread1 = new Thread(new MyTask());
  5. final Thread thread2 = new Thread(new MyTask());
  6. System.out.println("Thread1 is alive? " + thread1.isAlive());
  7. System.out.println("Thread2 is alive? " + thread2.isAlive());
  8. thread1.start();
  9. thread2.start();
  10. while (thread1.isAlive() || thread2.isAlive()) {
  11. System.out.println("Thread1 is alive? " + thread1.isAlive());
  12. System.out.println("Thread2 is alive? " + thread2.isAlive());
  13. Thread.sleep(500l);
  14. }
  15. System.out.println("Thread1 is alive? " + thread1.isAlive());
  16. System.out.println("Thread2 is alive? " + thread2.isAlive());
  17. System.out.println("Thread main finished");
  18. }
  19. }
  20. class MyTask implements Runnable {
  21. @Override
  22. public void run() {
  23. for (int i = 0; i < 5; i++) {
  24. System.out.println("[" + Thread.currentThread().getName() + "] Message " + i);
  25. try {
  26. Thread.sleep(200);
  27. } catch (final InterruptedException e) {
  28. e.printStackTrace();
  29. }
  30. }
  31. }
  32. }

输出。

  1. Thread main started
  2. Thread1 is alive? false
  3. Thread2 is alive? false
  4. Thread1 is alive? true
  5. Thread2 is alive? true
  6. [Thread-0] Message 0
  7. [Thread-1] Message 0
  8. [Thread-1] Message 1
  9. [Thread-0] Message 1
  10. [Thread-1] Message 2
  11. [Thread-0] Message 2
  12. Thread1 is alive? true
  13. Thread2 is alive? true
  14. [Thread-0] Message 3
  15. [Thread-1] Message 3
  16. [Thread-1] Message 4
  17. [Thread-0] Message 4
  18. Thread1 is alive? false
  19. Thread2 is alive? false
  20. Thread main finished

Thread.setPriority()方法

每个线程都有一个优先级。优先级用1到10之间的数字表示。在大多数情况下,线程调度器会根据线程的优先级来调度它们(称为抢占式调度)。但这并不保证,因为这取决于JVM的规范,它选择哪种调度方式。

在Thread类中定义了三个常量。

1.公共静态int MIN_PRIORITY
1.公共静态int NORM_PRIORITY

  1. 公共静态int MAX_PRIORITY 线程的默认优先级是5(NORM_PRIORITY)。MIN_PRIORITY的值是1,MAX_PRIORITY的值是10。
    给线程设置优先级 例子
  1. public class ThreadPriorityExample {
  2. public static void main(final String[] args) {
  3. final Runnable runnable = () -> {
  4. System.out.println("Running thread name : " + Thread.currentThread().getName() +
  5. " and it's priority : " + Thread.currentThread().getPriority());
  6. };
  7. final Thread thread1 = new Thread(runnable);
  8. final Thread thread2 = new Thread(runnable);
  9. final Thread thread3 = new Thread(runnable);
  10. final Thread thread4 = new Thread(runnable);
  11. thread1.setPriority(Thread.MIN_PRIORITY);
  12. thread2.setPriority(Thread.NORM_PRIORITY);
  13. thread3.setPriority(Thread.MAX_PRIORITY);
  14. thread4.setPriority(2);
  15. thread1.start();
  16. thread2.start();
  17. thread3.start();
  18. thread4.start();
  19. }
  20. }

输出:

  1. Running thread name : Thread-0 and it's priority : 1
  2. Running thread name : Thread-1 and it's priority : 5
  3. Running thread name : Thread-2 and it's priority : 10
  4. Running thread name : Thread-3 and it's priority : 2

Thread.setName()方法

java.lang.Thread类提供了改变和获得线程名称的方法。默认情况下,每个线程都有一个名字,即thread-0, thread-1 等等。通过使用setName()方法,我们可以改变线程的名称。setName() and getName()方法的语法如下。

  • public String getName(): 用于返回线程的名称。
  • public void setName(String name): 用于改变一个线程的名称。
    线程类提供了一个静态的currentThread() - 返回对当前执行的线程对象的引用。

命名一个线程的例子

  1. /**
  2. * Thread naming example using Thread class.
  3. * @author Ramesh fadatare
  4. **/
  5. public class ThreadExample {
  6. public static void main(final String[] args) {
  7. System.out.println("Thread main started");
  8. final Thread thread1 = new WorkerThread();
  9. thread1.setName("WorkerThread1");
  10. final Thread thread2 = new WorkerThread();
  11. thread2.setName("WorkerThread2");
  12. final Thread thread3 = new WorkerThread();
  13. thread3.setName("WorkerThread3");
  14. final Thread thread4 = new WorkerThread();
  15. thread4.setName("WorkerThread4");
  16. thread1.start();
  17. thread2.start();
  18. thread3.start();
  19. thread4.start();
  20. System.out.println("Thread main finished");
  21. }
  22. }
  23. class WorkerThread extends Thread {
  24. @Override
  25. public void run() {
  26. System.out.println("Thread Name :: " + Thread.currentThread().getName());
  27. }
  28. }

输出

  1. Thread main started
  2. Thread Name :: WorkerThread1
  3. Thread Name :: WorkerThread2
  4. Thread Name :: WorkerThread3
  5. Thread main finished
  6. Thread Name :: WorkerThread4

相关文章

最新文章

更多