调用线程异步堵塞方法

一 基本概念的理解

  1.1线程中断方法 ——interrupt() 

当调用一个线程的interrupt方法时候,线程并没有真的被中断,只是对其状态改变,线程会有一个boolean变量isInterrputed。有wait sleep方法会阻塞线程。

     wait 和sleep方法都会使得线程挂起,阻塞。区别是wait会释放资源,而sleep方法并不会释放资源。一旦执行wait方法后,线程立即被挂起,直到有其他线程调用资源的notify方法。具体参见博客,多线程资源争用问题:

   http://blog.csdn.net/leixingbang1989/article/details/24451527

  当线程执行了wait sleep方法后,线程阻塞,由于线程已经不再占用cpu资源,因此当调用线程的interrput方法会产生异常。(原因:线程都不再运行了,线程当然也就不能执行Interrpute方法).

1.2在线程已经阻塞的情况下,调用interrput方法会导致线程立即结束阻塞。

来看下面一个例子代码:

package Interrupt;

public class TestSleep implements Runnable {

    @Override
    public void run() {
        try {
            Thread.sleep(10000); //休眠10s
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public static void main(String[] ars) {
        TestSleep test = new TestSleep();
        Thread th = new Thread(test);
        th.start();
        long time = System.currentTimeMillis();
        while (System.currentTimeMillis() - time < 5000) {

        }
        th.interrupt();
    }
}

 

程序运行的基本过程如下图所示:

调用线程异步堵塞方法_第1张图片

 

在实际的运行过程当中 我们可以通过观察eclipse中的运行状态:

调用线程异步堵塞方法_第2张图片

 

发现在程序运行到5s时,程序便终止,在这里只是结束休眠,会接着运行休眠后的语句。因此调用interrput方法会导致线程立即结束阻塞,并抛出异常。但是抛出异常并不意味着程序会因此而直接终止。

我们来看下面一段代码:

public class TestInterrupt implements Runnable {

    @Override
    public void run() {
        while (true) {
            try {
                Thread.sleep(5000);
                System.out.println("running");
            } catch (Exception e) {
                e.printStackTrace();
                System.out.println("出现异常....");
            }
        }
    }
    public static void main(String[] ars) {
        TestInterrupt test = new TestInterrupt();
        Thread th = new Thread(test);
        th.start();
        long time = System.currentTimeMillis(); //去系统时间的毫秒数  
        while (System.currentTimeMillis() - time <= 10000) {

        }
        th.interrupt();
    }

}

程序非常简单,每隔5s输出一个正在运行的字符串,当出现异常时候,打印出来。程序执行结果如下:

running

running

java.lang.InterruptedException: sleep interrupted

    atjava.lang.Thread.sleep(Native Method)

出现异常....

    atInterrupt.TestInterrupt.run(TestInterrupt.java:10)

    atjava.lang.Thread.run(Unknown Source)

running

running

此运行结果说明,虽然抛出了异常,但是线程并不终止运行。

二 线程同步实例

如果想创建一个同步安全的链表 则应该使用以下方法

ArrayListarrayList=Collections.synchronizedList(new ArrayList());

调用线程异步堵塞方法_第3张图片

 


 
  1. 来看异步线程实例代码

    package sychronize;
    import java.util.LinkedList; //所有线程可以同时对其访问
    import java.io.*;
    import java.lang.Thread;
    import java.util.Scanner;
    public class unSynchronizedWrite {
        public static void main(String[] ars) throws Exception {
            final LinkedList < String > data = new LinkedList < String > ();
            //多个线程可以同时进行操作 
            File file = new File("unsync.txt");
            if (!file.exists()) {
                file.createNewFile();
            }

            final PrintWriter pw = new PrintWriter(new FileOutputStream(file));
            final Thread writerThread = new Thread() {
                public void run() {
                    boolean isInterrupted = false;
                    while (true) {
                        if (data.isEmpty()) //何时会收到中断指令?
                        {
                            if (isInterrupted) //收到中断指令 并且data数据位空 则直接写入数据 并中断线程
                            {
                                pw.flush();
                                break;
                            }
                            try {
                                Thread.sleep(10000); //休眠10s注意 一定要写捕获异常
                            } catch (InterruptedException e) {
                                isInterrupted = true; //一旦调用interrput方法后 会抛出异常马上停止休眠 程序继续执行
                                //    e.printStackTrace();
                            }
                        } else {
                            pw.println(data.removeFirst()); //向第一个写入
                        }
                    }
                }
            };
            System.out.println("输入内容:");
            final Thread reader = new Thread() {

                public void run() {
                    Scanner scanner = new Scanner(System.in);
                    String str = "";
                    while (true) {
                        str = scanner.nextLine(); //录入一行
                        if (str.equalsIgnoreCase("q")) {
                            writerThread.interrupt(); //线程并没有真正的被中断
                            break; //结束线程
                        }
                        data.addLast(str);
                    }
                }
            };
            writerThread.start();
            reader.start();
        }

    }

你可能感兴趣的:(Java面向对象)