多线程学习笔记--第一章 多线程技能(2)

1.currentThread方法
该方法返回代码段正在被哪个线程调用的信息。

2.isAlive方法
判断当前线程是否处于活动状态。活动状态是线程已经启动且尚未终止。线程处于运行或准备开始运行的状态。
如果将线程对象以构造参数的方式传递给Thread对象进行start启动时,结果与直接启动由差异,原因来自于Thread.currentThread()和this的差异。

3.sleep方法
在指定的毫秒数内让当前“正在执行的线程”休眠。正在执行的线程是指this.currentThread返回的线程。

4.getId方法
取得线程唯一标识。

5.停止线程
停止线程就是在线程处理完任务之前停止操作。停止一个线程可以使用Thread.stop方法,但最好不用它。该方法不安全,已被弃用。多数停止一个线程的操作使用Thread.interrupt方法,但这个方法不会终止一个正在运行的线程,需要加入一个判断才能完成线程停止。
三种终止线程:

  1. 使用退出标志,使线程正常退出,也就是run方法完成后终止。
  2. 使用stop方法
  3. 使用interrupt方法

interrupt方法并不能使线程停止,仅仅在当前线程中打一个停止标记。

判断线程是否是停止状态:

  1. this.interrupted():测试当前线程是否已经中断。执行后具有将状态标志清除为false功能
  2. this.isInterrupted():测试线程是否已经中断。但不清除标志。

异常法停止线程

public class MyThread{

	public static void main(String[] args){
		try{
			Thread6 t6=new Thread6();
			t6.start();
			Thread.sleep(2000);
			t6.interrupt();
		}catch(InterruptedException e){
			System.out.println("main catch");
			e.printStackTrace();
		}
		System.out.println("end!");
	}
}


public class Thread6 extends Thread{
	/**
	 * 异常法停止线程
	 */
	@Override
	public void run() {
		// TODO 自动生成的方法存根
		super.run();
		try{
			for(int i=0;i<500000;i++){
				if(this.interrupted()){
					System.out.println("已经是停止状态!退出!");
					throw new InterruptedException();
				}
				System.out.println("i="+(i+1));
			}
			System.out.println("我在for后面!线程还没有停止");
		}catch(InterruptedException e){
			System.out.println("进入Thread6.java的catch了!");
			e.printStackTrace();
		}
	}
}

i=209513
i=209514
i=209515
i=209516
i=209517
end!
已经是停止状态!退出!
进入Thread6.java的catch了!
java.lang.InterruptedException
	at Thread6.run(Thread6.java:14)

沉睡中停止


public class MyThread{

	public static void main(String[] args){
		try{
			Thread7 t7=new Thread7();
			t7.start();
			Thread.sleep(2000);
			t7.interrupt();
		}catch(InterruptedException e){
			System.out.println("main catch");
			e.printStackTrace();
		}
		System.out.println("end!");
	}
}


public class Thread7 extends Thread{

	/**
	 * 沉睡中停止线程
	 */
	@Override
	public void run() {
		// TODO 自动生成的方法存根
		super.run();
		try{
			System.out.println("run begin");
			Thread.sleep(200000);
			System.out.println("run end");
		}catch(InterruptedException e){
			System.out.println("在沉睡中被停止,进入catch!"+this.isInterrupted());
			e.printStackTrace();
		}
	}
}

run begin
end!
在沉睡中被停止,进入catch!false
java.lang.InterruptedException: sleep interrupted
	at java.lang.Thread.sleep(Native Method)
	at Thread7.run(Thread7.java:13)

可知,在sleep状态下停止某一线程,进入catch,并清除停止状态值,变为false。


public class MyThread{

	public static void main(String[] args){
		Thread8 t8=new Thread8();
		t8.start();
		t8.interrupt();
		System.out.println("end!");
	}
}


public class Thread8 extends Thread{

	/**
	 * 先停止,再sleep
	 */
	@Override
	public void run() {
		// TODO 自动生成的方法存根
		super.run();
		try{
			for(int i=0;i<100000;i++){
				System.out.println("i="+(i+1));
			}
			System.out.println("run begin");
			Thread.sleep(200000);
			System.out.println("run end");
		}catch(InterruptedException e){
			System.out.println("先停止,再遇到sleep,进入catch!");
			e.printStackTrace();
		}
	}
}

i=99998
i=99999
i=100000
run begin
先停止,再遇到sleep,进入catch!
java.lang.InterruptedException: sleep interrupted
	at java.lang.Thread.sleep(Native Method)
	at Thread8.run(Thread8.java:16)

与之相反的操作


public class MyThread{

	public static void main(String[] args){
		Thread9 t9=new Thread9();
		t9.start();
		t9.interrupt();
		System.out.println("end!");
	}
}


public class Thread9 extends Thread{
	/*
	 *先停止,再遇到sleep 
	 */
	@Override
	public void run() {
		// TODO 自动生成的方法存根
		super.run();
		try{
			for(int i=0;i<100000;i++){
				System.out.println("i="+(i+1));
			}
			System.out.println("run begin");
			Thread.sleep(200000);
			System.out.println("run end");
		}catch(InterruptedException e){
			System.out.println("先停止,在进入sleep,进入catch!");
			e.printStackTrace();
		}
	}
}

i=99999
i=100000
run begin
先停止,在进入sleep,进入catch!
java.lang.InterruptedException: sleep interrupted
	at java.lang.Thread.sleep(Native Method)
	at Thread9.run(Thread9.java:15)

暴力停止
使用stop方法停止线程。


public class MyThread{

	public static void main(String[] args){
		try{
			Thread10 t10=new Thread10();
			t10.start();
			Thread.sleep(8000);
			t10.stop();
			System.out.println("end!");
		}catch(InterruptedException e){
			e.printStackTrace();
		}
	}
}


public class Thread10 extends Thread{

	/*
	 * 使用stop停止
	 */
	private int i=0;
	@Override
	public void run() {
		// TODO 自动生成的方法存根
		try{
			while(true){
				i++;
				System.out.println("i="+i);
				Thread.sleep(1000);
			}
		}catch(InterruptedException e){
			e.printStackTrace();
		}
	}
}

i=1
i=2
i=3
i=4
i=5
i=6
i=7
i=8
end!

方法stop与java.lang.ThreadDeath异常
调用stop时会抛出java.lang.ThreadDeath异常。通常情况下,不需要显示捕捉。
stop方法已经被废弃,因为如果强制让线程停止可能使一些清理性的工作得不到完成。对锁定的对象进行解锁,导致数据得不到同步处理,出现数据不一致。

释放锁的不良后果
使用stop释放锁会造成数据不一致性结果。


public class MyThread{

	public static void main(String[] args){
		try{
			SynchronizedObject object=new SynchronizedObject();
			Thread11 t11=new Thread11(object);
			t11.start();
			Thread.sleep(500);
			t11.stop();
			System.out.println(object.getUsername()+" "+object.getPassword());
		}catch(InterruptedException e){
			e.printStackTrace();
		}
	}
}


public class SynchronizedObject {

	/*
	 * stop释放锁
	 */
	private String username="a";
	private String password="aa";
	public String getUsername(){
		return username;
	}
	
	public void setUsername(String username){
		this.username=username;
	}
	
	public String getPassword(){
		return password;
	}
	
	public void setPassword(String password){
		this.password=password;
	}
	
	synchronized public void printString(String username,String password){
		try{
			this.username=username;
			Thread.sleep(100000);
			this.password=password;
		}catch(InterruptedException e){
			e.printStackTrace();
		}
	}
	
}


public class Thread11 extends Thread{
	/*
	 * stop释放锁
	 */

	private SynchronizedObject object;
	public Thread11(SynchronizedObject object){
		super();
		this.object=object;
	}
	@Override
	public void run() {
		// TODO 自动生成的方法存根
		object.printString("b", "bb");
	}
}

使用return停止线程
将方法interrupt与return结合可以实现停止线程效果。


public class MyThread{

	public static void main(String[] args){
		Thread12 t12=new Thread12();
		t12.start();
		try {
			Thread.sleep(2000);
		} catch (InterruptedException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}
		t12.interrupt();
	}
}


public class Thread12 extends Thread{

	/*
	 * 使用return+interrupt停止线程
	 */
	@Override
	public void run() {
		// TODO 自动生成的方法存根
		while(true){
			if(this.isInterrupted()){
				System.out.println("stop!!!");
				return;
			}
			System.out.println("timer="+System.currentTimeMillis());
		}
	}
}

timer=1550561473006
timer=1550561473006
timer=1550561473006
timer=1550561473006
stop!!!

建议使用“抛出异常”方法来实现线程停止,因为catch中的异常还可以向上抛,使得线程停止事件得以传播。

参考书籍《java多线程编程核心技术》

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值