java并发(Concurrency)《二线程》 ---来源于oracle官网

线程策略

每个线程都是Thread类的实例,用Thread对象去创建一个并发应用要遵循两个基本策略:

  1. 直接控制线程的创建和管理,只是每次实例化线程应用程序需要发起异步任务
  2. 从应用中抽象线程的管理,将任务传递给处理器

定义和开启线程

创建Thread实例的应用必须提供在该线程当中运行的核心方法,有两种方法实现

实现Runnable类

Runnable接口定义了run(),run方法执行核心的线程逻辑。Runnable对象需要传递给Thread constructor。

public class HelloRunnable implements Runnable {
    public void run() {
        System.out.println("Hello from a thread!");
    }
    public static void main(String args[]) {
        (new Thread(new HelloRunnable())).start();
    }
}
继承Thread类

Thread类本身实现了Runnable,尽管它本身的run方法没有做任何事。一个类可以继承Thread类,定义自己的run方法

public class HelloThread extends Thread {

    public void run() {
        System.out.println("Hello from a thread!");
    }
    public static void main(String args[]) {
        (new HelloThread()).start();
    }
}

注意:两种方式都是调用 start()来开启一个线程。我们推荐使用implements Runnable 的方式开启。

暂缓执行(Thread.sleep())

public class SleepMessages {
    public static void main(String args[])
        throws InterruptedException {
        String importantInfo[] = {
            "Mares eat oats",
            "Does eat oats",
            "Little lambs eat ivy",
            "A kid will eat ivy too"
        };

        for (int i = 0;
             i < importantInfo.length;
             i++) {
            //Pause for 4 seconds
            Thread.sleep(4000);
            //Print a message
            System.out.println(importantInfo[i]);
        }
    }
}

线程中断(Interrupts)

interrupt指令告诉线程在一个适当的时间点中断,真正的中断要基于程序本身。
线程执行interrupt() 去发起中断指令,为了中断过程正确进行,被发起中断的线程本身必须支持被中断(即监听线程状态,在中断时候做点事情)
一个线程如何支持自己的中断?这取决于它是目前做什么。如果线程是抛出InterruptedException频繁调用的方法,则return 即可。

for (int i = 0; i < importantInfo.length; i++) {
    // Pause for 4 seconds
    try {
        Thread.sleep(4000);
    } catch (InterruptedException e) {
        // We've been interrupted: no more messages.
        return;
    }
    // Print a message
    System.out.println(importantInfo[i]);
}

许多方法会抛出InterruptedException异常,例如Thread.sleep()就是被用来取消当前的操作并且当接收到interrupt指令之后相应的。
如果一个线程是很长一段时间没有调用一个方法抛出InterruptedException时,那么它必须定期调用Thread.interrupted,返回true,如果中断已经收到。例如:

for (int i = 0; i < inputs.length; i++) {
    heavyCrunch(inputs[i]);
    if (Thread.interrupted()) {
        // We've been interrupted: no more crunching.
        return;
    }
}

也可以

if (Thread.interrupted()) {
    throw new InterruptedException();
}
线程中断的状态 (The Interrupt Status Flag)

The interrupt mechanism is implemented using an internal flag known as the interrupt status. Invoking Thread.interrupt sets this flag. When a thread checks for an interrupt by invoking the static method Thread.interrupted, interrupt status is cleared. The non-static isInterrupted method, which is used by one thread to query the interrupt status of another, does not change the interrupt status flag.
By convention, any method that exits by throwing an InterruptedException clears interrupt status when it does so. However, it’s always possible that interrupt status will immediately be set again, by another thread invoking interrupt.

中断机制依赖一个内部的flag — interrupt status(通过实现Thread.interrupt()设置)。当线程检测到调用了该静态方法Thread.interrupted之后,interrupt status就会被清除。Thread.isInterrupted(非静态)方法则是用来查询interrupt status。
通常任何方法抛出InterruptedException时候就会清除interrupt status,然而也有可能interrupt status又会被另一个线程调用中断设置。

Joins方法

假设t是一个线程实例,t.join()表示停止当前程序逻辑,直到t线程终止。join也可以传timing的参数,您可以自定义等待时间。(同 sleep)

单线程案例 The SimpleThreads Example

public class SimpleThreads {

    // Display a message, preceded by
    // the name of the current thread
    static void threadMessage(String message) {
        String threadName =
            Thread.currentThread().getName();
        System.out.format("%s: %s%n",
                          threadName,
                          message);
    }

    private static class MessageLoop
        implements Runnable {
        public void run() {
            String importantInfo[] = {
                "Mares eat oats",
                "Does eat oats",
                "Little lambs eat ivy",
                "A kid will eat ivy too"
            };
            try {
                for (int i = 0;
                     i < importantInfo.length;
                     i++) {
                    // Pause for 4 seconds
                    Thread.sleep(4000);
                    // Print a message
                    threadMessage(importantInfo[i]);
                }
            } catch (InterruptedException e) {
                threadMessage("I wasn't done!");
            }
        }
    }

    public static void main(String args[])
        throws InterruptedException {

        // Delay, in milliseconds before
        // we interrupt MessageLoop
        // thread (default one hour).
        long patience = 1000 * 60 * 60;

        // If command line argument
        // present, gives patience
        // in seconds.
        if (args.length > 0) {
            try {
                patience = Long.parseLong(args[0]) * 1000;
            } catch (NumberFormatException e) {
                System.err.println("Argument must be an integer.");
                System.exit(1);
            }
        }

        threadMessage("Starting MessageLoop thread");
        long startTime = System.currentTimeMillis();
        Thread t = new Thread(new MessageLoop());
        t.start();

        threadMessage("Waiting for MessageLoop thread to finish");
        // loop until MessageLoop
        // thread exits
        while (t.isAlive()) {
            threadMessage("Still waiting...");
            // Wait maximum of 1 second
            // for MessageLoop thread
            // to finish.
            t.join(1000);
            if (((System.currentTimeMillis() - startTime) > patience)
                  && t.isAlive()) {
                threadMessage("Tired of waiting!");
                t.interrupt();
                // Shouldn't be long now
                // -- wait indefinitely
                t.join();
            }
        }
        threadMessage("Finally!");
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值