Java 并发编程——线程

本文详细介绍了Java中多线程的实现方法,包括继承Thread类和实现Runnable接口两种方式。探讨了如何使用interrupt()方法中断线程,以及如何通过isInterrupted()和Thread.interrupted()方法来判断线程的中断状态。此外,还介绍了线程的各种状态及其转换过程。

多线程的实现方法

Java 中实现多线程有两种方法:继承 Thread 类、实现 Runnable 接口

使用 interrupt()中断线程

当对一个线程调用 interrupt 方法时,线程的中断状态将被置位。这是每一个线程都具有
的 boolean 标志。每个线程都应该不时地检査这个标志, 以判断线程是否被中断。

package com.ping;

import java.util.logging.Logger;

/**
 * @author zwp
 * @version 1.00 2018/8/22.
 */
public class SleepInterrupt extends Object implements Runnable{
    public void run(){
        while (!Thread.currentThread().isInterrupted())
        {
            System.out.println("Interrupted状态:"+Thread.currentThread().isInterrupted());

        }
        if (Thread.currentThread().isInterrupted()) {

            System.out.println("Interrupted状态:"+Thread.currentThread().isInterrupted());

            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                //sleep遇到Interrupted状态为true会抛出InterruptedException异常
                e.printStackTrace();
                System.out.println("抛出异常后Interrupted状态:"+Thread.currentThread().isInterrupted());
            }
        }

        System.out.println("in run() - 线程运行完毕");
    }

    public static void main(String[] args) throws InterruptedException {
        SleepInterrupt si = new SleepInterrupt();
        Thread t = new Thread(si);
        t.start();
        //主线程休眠,从而确保刚才启动的线程有机会执行一段时间
        try {
            Thread.sleep(100);
        }catch(InterruptedException e){
            e.printStackTrace();
        }
        System.out.println("in main() - 对t线程使用interrupt()");
        //中断线程t
        t.interrupt();
        System.out.println("in main() - 对t线程使用interrupt() OK");
        Thread.sleep(2000);
        System.out.println("in main() - 主线程完毕");

    }
}

使用 isInterrupted()方法判断中断状态

可以在 Thread 对象上调用 isInterrupted()方法来检查任何线程的中断状态。这里需要注意:线程一旦被中断,isInterrupted()方法便会返回 true,而一旦 sleep()方法抛出异常,它将清空中断标志,此时isInterrupted()方法将返回 false。

使用 Thread.interrupted()方法判断中断状态

测试当前线程(即正在执行这一命令的线程)是否被中断。注意,这是一个静态方法。这一调用会产生副作用 —— 它将当前线程的中断状态重置为 false。

线程状态

线程状态可以有以下6种:
1. New (新创建)
2. Runnable (可运行)
3. Blocked (被阻塞)
4. Waiting (等待)
5. Timed waiting (计时等待)
6. Terminated (被终止)

要确定一个线程的当前状态, 可调用 getState 方法。

新创建线程:当用 new 操作符创建一个新线程时,如 newThread(r), 该线程还没有开始运行。

可运行线程:一个可运行的线程可能正在运行也可能没有运行, 这取决于操作系统给线程提供运行的时间。

被阻塞线程和等待线程:当线程处于被阻塞或等待状态时,它暂时不活动。它不运行任何代码且消耗最少的资
源。直到线程调度器重新激活它。

  • 当一个线程试图获取一个内部的对象锁(而不是 javiutiUoncurrent 库中的锁,) 而该锁被其他线程持有, 则该线程进人阻塞状态。
  • 当所有其他线程释放该锁,并且线程调度器允许本线程持有它的时候,该线程将变成非阻塞状态。
  • 当线程等待另一个线程通知调度器一个条件时,它自己进入等待状态。在调用 Object.wait 方法或 Thread.join 方法, 或者是等待 java,util.concurrent 库中的 Lock 或 Condition 时,
    就会出现这种情况。实际上,被阻塞状态与等待状态是有很大不同的。
  • 有几个方法有一个超时参数。调用它们导致线程进人计时等待( timed waiting ) 状态。这一状态将一直保持到超时期满或者接收到适当的通知。带有超时参数的方法有Thread.sleep 和
    Object.wait、Thread.join、 Lock,tryLock 以及 Condition.await 的计时版。

被终止的线程:因为 run 方法正常退出而自然死亡。因为一个没有捕获的异常终止了 nm 方法而意外死亡。可以调用线程的 stop 方法杀死一个线程,该方法抛出 ThreadDeath 错误对象,由此杀死线程。

  • void stop() 停止该线程。这一方法已过时。
  • void suspend() 暂停这一线程的执行。这一方法已过时。
  • void resume() 恢复线程。这一方法仅仅在调用 suspendO 之后调用。这一方法已过时。

线程优先级

在 Java 程序设计语言中,每一个线程有一个优先级。默认情况下, 线程继承它的父
线程的优先级。
每当线程调度器有机会选择新线程时, 它首先选择具有较高优先级的线程。但是,线程
优先级是高度依赖于系统的。

void setPriority(int newPriority) 设置线程的优先级。
static int MIN_PRIORITY 线程的最小优先级。最小优先级的值为 1。
static int N0RM_PRI0RITY 线程的默认优先级。默认优先级为 5。
static int MAX_PRIORITY 线程的最高优先级。最高优先级的值为 10。
static void yield( ) 导致当前执行线程处于让步状态。如果有其他的可运行线程具有至少与此线程同样高的优先级,那么这些线程接下来会被调度。注意,这是一个静态方法

守护线程

Java 中有两类线程:User Thread(用户线程)、Daemon Thread(守护线程)。

setDaemon(true)方法设置当前线程为守护线程。
虽然守护线程可能非常有用,但必须小心确保其他所有非守护线程消亡时,不会由于它的终止而产生任何危害。因为你不可能知道在所有的用户线程退出运行前,守护线程是否已经完成了预期的服务任务。一旦所有的用户线程退出了,虚拟机也就退出运行了。

  • setDaemon(true)必须在调用线程的 start()方法之前设置,否则会跑出IllegalThreadStateException 异常。
  • 在守护线程中产生的新线程也是守护线程。

线程阻塞

线程可以阻塞于四种状态:

  • 当线程执行 Thread.sleep()时,它一直阻塞到指定的毫秒时间之后,或者阻塞被另一个线程打断;
  • 当线程碰到一条 wait()语句时,它会一直阻塞到接到通知(notify())、被中断或经过了指定毫秒时间为止(若制定了超时值的话)
  • 线程阻塞与不同 I/O 的方式有多种。常见的一种方式是
    InputStream的read()方法,该方法一直阻塞到从流中读取一个字节的数据为止,它可以无限阻塞,因此不能指定超时时间;
  • 线程也可以阻塞等待获取某个对象锁的排他性访问权限(即等待获得 synchronized 语句必须的锁时阻塞)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值