Java多线程与并发学习之(四):线程常用方法

java线程对象有一些经常使用的方法,如:

(1).currentThread():返回代码段正在被哪个线程调用。

(2).isAlive():判断当前线程是否处于活动状态。

(3).getId():返回线程唯一标示。

(4).interrupt():中断线程。

(5).interrupted():判断当前线程是否已经中断。

(6).isInterrupt():判断线程是否已经中断。

(7).stop():将线程强制停止。

(8).suspend():暂停线程。

(9).resume():恢复线程执行。

(10).yield():放弃当前的CPU资源,将它让给其他任务去占用CPU执行时间。


下面逐一举例说明各方法作用。

(1).currentThread():返回代码段正在被哪个线程调用

public class Run1 {
	public static void main(String[] args) {
		System.out.println("当前线程名称:" + Thread.currentThread().getName());
	}
}
输出为:“当前线程名称:main”,说明main方法被名为main的线程调用。
public class MyThread1 extends Thread{
	public MyThread1(){
		System.out.println("构造方法的打印:" + Thread.currentThread().getName());
	}
	@Override
	public void run(){
		System.out.println("run方法的打印:" + Thread.currentThread().getName());
	}
}
 public class Run1 {
	public static void main(String[] args) {
		MyThread1 thread = new MyThread1();
		thread.start();
		//thread.run();
	}
}

当执行thread.start();方法和thread.run();方法打印结果分别为:




    打印结果不同的原因在于调用start()方法时,启动了新的线程,run方法是被新线程来执行的,构造方法两种情况都是被main线程执行,直接调用run方法时,并未启动新线程,直接通过main线程执行的run方法,所以两次打印结果不同。

    很多时候Thread.currentThread().getName()会与this.getName()方法进行比较,其实比较的是currentThread和this获取到线程这两种方式的区别。

a.Thread.currentThread()在两种实现线程的方式(实现Runnable接口和继承Thread类)中都可以使用;this方式只能在继承方式中使用;

b.currentThread()方法返回的是对当前正在执行的线程的引用,this代表的是当前调用它所在函数所属的对象的引用。


(2).isAlive():判断当前线程是否处于活动状态。

public class Run1 {
	public static void main(String[] args) {
		MyThread2 thread = new MyThread2();
		System.out.println("begin = " + thread.isAlive());
		thread.start();
		System.out.println("end = " + thread.isAlive());
	}
}

    什么是活动状态呢,活动状态就是线程已经启动且尚未终止。线程处于正在运行或准备开始运行的状态,就认为线程是“存活”的。

    其实上面的结果中end后的状态是不确定的,有可能是true也可能是false,看main线程执行end这行时,thread线程是否已经执行完毕了,这个地方打印的是true是因为thread线程还未执行完毕。


(3).getId():返回线程唯一标示。

public class Run1 {
	public static void main(String[] args) {
		MyThread2 thread = new MyThread2();
		System.out.println(thread.getName() + "  " + thread.getId());
	}
}
输出为:Thread-0  10


(4).interrupt():中断线程。

(5).interrupted():判断当前线程是否已经中断。

(6).isInterrupt():判断线程是否已经中断。

(7).stop():将线程强制停止。

    这几个方法一起说,因为这三个方法都是跟停止线程或判断线程中断状态相关。java中有三种方法可以终止正在运行的线程:

a.使用退出标志,使线程正常退出,也就是当run方法完成后线程终止;

b.使用stop方法强行终止线程,但是不推荐使用这个方法,因为stop和suspend(暂停线程)及resume(恢复线程执行)一样,都是作废过期方法,使用它们可能产生不可预料的结果;

c.使用interrupt方法中断线程。


    interrupt():线程的thread.interrupt()方法是中断线程,将会设置该线程的中断状态位,即设置为true,中断的结果线程是死亡、还是等待新的任务或是继续运行至下一步,就取决于这个程序本身。线程会不时地检测这个中断标示位,以判断线程是否应该被中断(中断标示值是否为true)。它并不像stop方法那样会中断一个正在运行的线程。如果线程在调用 Object 类的 wait()、wait(long) 或 wait(long, int) 方法,或者该类的 join()、join(long)、join(long, int)、sleep(long) 或 sleep(long, int) 方法过程中受阻,则其中断状态将被清除,它还将收到一个 InterruptedException。也就是说,interrupt()方法并不会真正中断一个线程,只是会设置线程的中断状态为true,当线程调用wait()、wait(long)这些方法产生阻塞时,会来判断线程的状态是否是中断,如果是,会抛出InterruptedException异常的方式中断线程。

public class MyThread2 extends Thread{
	@Override
	public void run(){
		super.run();
		for (int i = 1; i <= 500000; i++) {
			System.out.println("i=" + i);
		}
	}
}
public class Run1 {
	public static void main(String[] args) {
		try {
		MyThread2 thread = new MyThread2();
		thread.start();
		Thread.sleep(1000);
		thread.interrupt();
		} catch (InterruptedException e) {
			System.out.println("main catch");
			e.printStackTrace();
		}
	}
}

   interrupted():测试当前线程是否已经中断,并且具有清除状态标志为false的作用。换句话说,如果连续两次调用该方法,则第二次调用将返回false(在第一次调用已经清除了其中中断状态之后,且第二次调用检验中断状态前,当前线程再次中断的情况除外)。

public class Run1 {
	public static void main(String[] args) {
		try {
			MyThread2 thread = new MyThread2();
			thread.start();
			Thread.sleep(50);
			thread.interrupt();
			System.out.println("是否停止1? = " + thread.interrupted());
			System.out.println("是否停止2? = " + thread.interrupted());
		} catch (InterruptedException e) {
			System.out.println("main catch");
			e.printStackTrace();
		}
		System.out.println("end!");
	}
}

    样例中虽然是在thread对象上调用的interrupt()方法来中断thread对象所代表的线程,在后面使用interrupted()方法来判断thread对象所代表的线程是否中断,但从输出来看,线程并未停止,这也说明了interrupted()方法的解释:测试当前线程是否已经中断。这个“当前线程”是main线程,它从未中断过,所以打印了两个false。

public class Run1 {
	public static void main(String[] args) {
		Thread.currentThread().interrupt();
		System.out.println("是否停止1? = " + Thread.interrupted());
		System.out.println("是否停止2? = " + Thread.interrupted());
		System.out.println("end!");
	}
}

    此时main线程产生了中断的效果。


   isInterrupt():测试线程Thread对象是否已经是中断状态,但不清除状态标志

public static void main(String[] args) {
		try {
			MyThread2 thread = new MyThread2();
			thread.start();
			Thread.sleep(50);
			thread.interrupt();
			System.out.println("是否停止1? = " + thread.isInterrupted());
			System.out.println("是否停止2? = " + thread.isInterrupted());
		} catch (InterruptedException e) {
			System.out.println("main catch");
			e.printStackTrace();
		}
		System.out.println("end!");
	}


   stop():暴力终止线程。

public class MyThread3 extends Thread{
	@Override
	public void run(){
		super.run();
		for (int i = 1; i <= 10000; i++) {
			System.out.println("i=" + i);
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}
public static void main(String[] args) {
		try {
			MyThread3 thread = new MyThread3();
			thread.start();
			Thread.sleep(5000);
			thread.stop();
		} catch (InterruptedException e) {
			System.out.println("main catch");
			e.printStackTrace();
		}
	}

   

    (8).suspend():暂停线程。

    (9).resume():恢复线程执行。

public class MyThread4 extends Thread{
	private long i = 0;
	
	public long getI() {
		return i;
	}
	public void setI(long i) {
		this.i = i;
	}

	@Override
	public void run(){
		super.run();
		while(true){
			i++;
		}
	}
}
public static void main(String[] args) {
		try {
			MyThread4 thread = new MyThread4();
			thread.start();
			Thread.sleep(5000);
			
			thread.suspend();
			System.out.println("A= " + System.currentTimeMillis() + "  i=" + thread.getI());
			Thread.sleep(5000);
			System.out.println("A= " + System.currentTimeMillis() + "  i=" + thread.getI());
			
			thread.resume();
			Thread.sleep(5000);
			
			thread.suspend();
			System.out.println("B= " + System.currentTimeMillis() + "  i=" + thread.getI());
			Thread.sleep(5000);
			System.out.println("B= " + System.currentTimeMillis() + "  i=" + thread.getI());
			
		} catch (InterruptedException e) {
			System.out.println("main catch");
			e.printStackTrace();
		}
	}

    suspend()方法和resume()方法是废弃方法,也不提倡使用,有独占和不同步的缺点。如果使用不当,极易造成公共的同步对象的独占,使得其他线程无法访问公共同步对象。


    (10).yield():放弃当前的CPU资源,将它让给其他任务去占用CPU执行时间。但放弃的时间不确定,有可能刚刚放弃,马上又获得CPU的时间片。

public class MyThread5 extends Thread{
	@Override
	public void run(){
		long beginTime = System.currentTimeMillis();
		long count = 0;
		for (int i = 0; i < 50000000; i++) {
			//Thread.yield();
			count = count + i;
		}
		long endTime = System.currentTimeMillis();
		System.out.println("计算结果count=" + count + ",用时:" + (endTime-beginTime) + "ms");
	}
}
public static void main(String[] args) {
	MyThread5 thread = new MyThread5();
	thread.start();
}
注释Thread.yield();这行时执行结果,很快;


不注释Thread.yield();这行时执行结果,让出CPU时间片时,相对来说要慢很多。









  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值