Java 线程操作的一些方法

本文介绍了Java多线程的基础知识,包括线程名称的获取与设置、判断线程是否启动、守护线程与setDaemon方法、线程的联合使用join()方法及线程的中断处理等核心概念。

一、取得和设置线程的名称

1.取得线程名称

package 多线程基础;

public class GetNameThread extends Thread
{
	
	public void run()
	{
		for(int i=0;i<3;i++)
		{
			printMsg();								//当前的其他线程调用printMsg()方法
			try {
				Thread.sleep(1000);                 //睡眠1s
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
	
	public void printMsg()
	{
		Thread t=Thread.currentThread();			//获得当前线程的名字
		String name=t.getName();
		System.out.println("name = "+name);
	}
	
    public  static void main(String [] args)
    {
	    GetNameThread t1=new GetNameThread();GetNameThread t2=new GetNameThread();
	    t1.start();
	    for(int i=0;i<5;i++)
	    {
	    	t1.printMsg();							//主线程调用printMsg()方法
	    	try {
				Thread.sleep(1000);					//主线程睡眠1s
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
	    }
    }
}

输出:

name = main
name = Thread-0
name = main
name = Thread-0
name = Thread-0
name = main
name = main
name = main

run( )方法只是类的一个普通方法而已,如果直接调用run( )方法,程序中依然只有主线程这一个线程,其程序执行路径依然只有一条,也就是说一旦run( )方法被调用,程序还要顺序执行,只有run( )方法具体执行完毕后,才可执行其后的代码,这样并没有达到多线程并发执行的目的。就如下面的代码,把t1.start();注释掉发现输出,只有main线程。

package 多线程基础;

public class GetNameThread extends Thread
{
	
	public void run()
	{
		for(int i=0;i<3;i++)
		{
			printMsg();								//当前的其他线程调用printMsg()方法
			try {
				Thread.sleep(1000);                 //睡眠1s
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
	
	public void printMsg()
	{
		Thread t=Thread.currentThread();			//获得当前线程的名字
		String name=t.getName();
		System.out.println("name = "+name);
	}
	
    public  static void main(String [] args)
    {
	    GetNameThread t1=new GetNameThread();GetNameThread t2=new GetNameThread();
	    //t1.start();
	    for(int i=0;i<5;i++)
	    {
	    	t1.printMsg();							//主线程调用printMsg()方法
	    	try {
				Thread.sleep(1000);					//主线程睡眠1s
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
	    }
    }
}
输出:

name = main
name = main
name = main
name = main
name = main

2.设置线程的名称

package 多线程基础;

public class GetSetName implements Runnable
{

	public void run ()
	{
		Thread temp=Thread.currentThread();
		System.out.println("当前线程的名称:"+temp.getName());	//取得当前线程的名字
	}
	public static void main(String[] args) {
		System.out.println("NI好!");
           Thread t=new Thread(new GetSetName());
           t.setName("我叫张昊雨!");							//设置线程的名字
          t.start();
	}

}

输出:

NI好!
当前线程的名称:我叫张昊雨!

二、判断线程是否启动

用到isAlive( ) 方法

package 多线程基础;

public class StartThread extends Thread
{
	public void run()
	{
		for(int i=0;i<5;i++)
		{
			printMsg();
		}
	}
    public void printMsg()
    {
    	//获取当前线程的引用
    	Thread t=Thread.currentThread();
    	String name =t.getName();
    	System.out.println("name = "+name);
    }
	public static void main(String[] args) 
	{
        StartThread t=new StartThread();
        //设置线程名字
        t.setName("张昊雨");
        System.out.println("调用start()之前,t.isalive()="+t.isAlive());
        t.start();
        System.out.println("调用start()之后,t.isalive()="+t.isAlive());
        for(int i=0;i<5;i++)
        {
        	t.printMsg();
        }
      //下面语句输出的结果是不固定的,有时输出false,有时输出true
        System.out.println("Main方法结束时,t.isalive="+t.isAlive());
	}

}

输出:

调用start()之前,t.isalive()=false
调用start()之后,t.isalive()=true
name = main
name = main
name = main
name = 张昊雨
name = 张昊雨
name = 张昊雨
name = 张昊雨
name = 张昊雨
name = main
name = main
Main方法结束时,t.isalive=false

三、守护线程与setDaemon方法

守护线程也叫后台线程,它是指用户程序在运行时后台提供的一种通用服务的线程。

例如垃圾回收的线程就属于守护线程

当线程中只剩下守护线程时JVM就会退出,如果还有其他的用户线程在,JVM就不会退出

查看Thread源码可知: 

private boolean daemon = false;

意味着默认创建的线程都属于偶同的用户线程。只有调用setDaemon(true)之后,才能转为守护线程。

package 多线程基础;

public class ThreadDaemon 
{
    public static void main(String [] args)
    {
    	Thread t=new Thread(new Threadtest());
    	t.setDaemon(true);				//设置为守护线程,一定要在start()之前
    	t.start();
    	
    	try {	//睡眠1毫秒,避免可能出现的没有输出的现象
			Thread.sleep(1);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
    }
}

class Threadtest implements Runnable
{
	public void run()
	{
		for(int i=0;true;i++) {
			System.out.println(i+" "+Thread.currentThread().getName()+"is running");
		}
	}
}
输出:

0 Thread-0is running
1 Thread-0is running
2 Thread-0is running
3 Thread-0is running
4 Thread-0is running
5 Thread-0is running
6 Thread-0is running
7 Thread-0is running
8 Thread-0is running
9 Thread-0is running
10 Thread-0is running
11 Thread-0is running
12 Thread-0is running
13 Thread-0is running
14 Thread-0is running
15 Thread-0is running
16 Thread-0is running
17 Thread-0is running
18 Thread-0is running
19 Thread-0is running
20 Thread-0is running
21 Thread-0is running
22 Thread-0is running
23 Thread-0is running
24 Thread-0is running
25 Thread-0is running
26 Thread-0is running
27 Thread-0is running
28 Thread-0is running
29 Thread-0is running
在这1毫秒之内输出了这些。虽然说run( ) 方法里的for循环是死循环,但因为该线程被设置成为守护线程,因此整个进程在主线程main结束后就随之停止了。可以想象,若果将t.setDaemon(true);注释掉,就会无限输出了。哈哈哈

四、线程的联合

用到join( ) 方法

package 多线程基础;

public class ThreadJoin {

	public static void main(String[] args) 
	{
       Thread ppThread=new Thread(new ttttt());
       ppThread.start();
       int i=0;
       for(int x=0;x<5;x++)
       {
    	   if(i==3)
    	   {
    		   try {
				ppThread.join();            //强制执行完ppThread线程后,再运行后面的程序,此时相当于main线程挂起了.
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
    	   }
    	   System.out.println("main Thread"+i);
    	   i++;
       }
	}

}

class ttttt implements Runnable
{
	public void run()
	{
		int i=0;
		for(int x=0;x<5;x++)
		{
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println(Thread.currentThread().getName()+"---->"+i);
			i++;
		}
	}
}
输出:

main Thread0
main Thread1
main Thread2
Thread-0---->0
Thread-0---->1
Thread-0---->2
Thread-0---->3
Thread-0---->4
main Thread3
main Thread4

在i=3时
主线程会阻塞,直到ppThread线程执行完main线程才会继续执行

五、线程的中断

范例1

package 多线程基础;

public class SleepInterrupt implements Runnable{
    public void run() {
        try{
            System.out.println( "在run()方法中 - 这个线程休眠10秒" );
            Thread.sleep( 10000 );
            System.out.println( "在run()方法中 - 继续运行" );
        }
       catch( InterruptedException x ){
            System.out.println( "在run()方法中 - 中断线程" );
            //return;
        }
        System.out.println( "在run()方法中 - 休眠之后继续完成" );
        System.out.println( "在run()方法中 - 正常退出" );
    }
    public static void main( String[] args ){
        SleepInterrupt si = new SleepInterrupt();
        Thread t = new Thread( si );
        t.start();
        // 在此休眠是为确保线程能运行一会
        try{
            Thread.sleep( 2000 );
        }
        catch( InterruptedException e ){
            e.printStackTrace();
        }
        System.out.println( "在main()方法中 - 中断其它线程" );
        t.interrupt();			//在main线程中断 t 线程
        System.out.println( "在main()方法中 - 退出" );
    }
}




输出;

在run()方法中 - 这个线程休眠10秒
在main()方法中 - 中断其它线程
在main()方法中 - 退出
在run()方法中 - 中断线程
在run()方法中 - 休眠之后继续完成
在run()方法中 - 正常退出

t 线程并没有休眠10s,而是休眠2s后背主线程中断了,它会抛出异常被catch抓到,所以会输出 在run()方法中 - 中断线程 这句话


范例2

package 多线程基础;



public class InteruptCheck
{
	public static void main( String[] args )
	{
		Thread t = Thread.currentThread();
		System.out.println( "A:t.isInterrupted() = " + t.isInterrupted() );
		//中断的是main线程
		t.interrupt();						
		System.out.println( "B:t.isInterrupted() = " + t.isInterrupted() );
		System.out.println( "C:t.isInterrupted() = " + t.isInterrupted() );
		try
		{
			Thread.sleep( 2000 );
			System.out.println( "线程没有被中断" );
		}
		catch( InterruptedException x )
		{
			System.out.println( "线程被中断" );
		}
		//因为sleep抛出了异常,所以它清除了中断标志
		System.out.println( "D:t.isInterrupted() = " + t.isInterrupted() );
	}
}



输出:

A:t.isInterrupted() = false
B:t.isInterrupted() = true
C:t.isInterrupted() = true
线程被中断
D:t.isInterrupted() = false

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

水之积也不厚,则其负大舟也无力

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值