线程异步学习(基于java学习笔记)

时间:2014-04-29 13:11:22   收藏:0   阅读:372

一 基本概念的理解

  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();
}
}

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

mamicode.com,码迷

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

mamicode.com,码迷

发现在程序运行到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());

mamicode.com,码迷

来看异步线程实例代码:
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学习笔记),码迷,mamicode.com

评论(0
© 2014 mamicode.com 版权所有 京ICP备13008772号-2  联系我们:gaon5@hotmail.com
迷上了代码!