Java线程基础

启动线程

  • 继承类Thread
  • 实现Runnable接口
  • 实现Callable接口(包装成FutureTask)
public class NewThread extends Thread{

	/*扩展自Thread类*/
	@Override
	public void run() {
		System.out.println("I am extends Thread");
	}

	
	/*实现Runnable接口*/
	private static class UseRun implements Runnable{

		@Override
		public void run() {
			System.out.println("I am implements Runnable");
		}
		
	}
	
	/*实现Callable接口,允许有返回值*/
	private static class UseCall implements Callable<String>{

		@Override
		public String call() throws Exception {
			System.out.println("I am implements Callable");
			return "CallResult";
		}
		
	}	
	
	public static void main(String[] args) 
			throws InterruptedException, ExecutionException {

		new NewThread().start();

		UseRun useRun = new UseRun();
		new Thread(useRun).start();
		Thread t = new Thread(useRun);
		t.interrupt();
		
		UseCall useCall = new UseCall();
		FutureTask<String> futureTask = new FutureTask<>(useCall);
		new Thread(futureTask).start();
		System.out.println(futureTask.get());
	}
}

执行结果:

I am extends Thread
I am implements Runnable
I am implements Callable
CallResult

停止线程

interrupt()中断一个线程,并不是强行关闭这个线程,把中断标志位置为true
isInterrupted()判断当前线程是否处于中断状态,判断中断标志位是否为true
interrupted()(static方法)判断当前线程是否处于中断状态,中断标志位改为false

public class EndRunnable {
	
	private static class UseRunnable implements Runnable{
		
		@Override
		public void run() {
			String threadName = Thread.currentThread().getName();
			
			System.out.println(threadName+" interrput flag is "
					+Thread.currentThread().isInterrupted());
					
			while(!Thread.currentThread().isInterrupted()) {
				System.out.println(threadName+" is run!");
			}
			System.out.println(threadName+" interrput flag is "
					+Thread.currentThread().isInterrupted());
		}			
	}

	public static void main(String[] args) throws InterruptedException {
		UseRunnable useRunnable = new UseRunnable();
		Thread endThread = new Thread(useRunnable,"endThread");
		endThread.start();
		Thread.sleep(1);
		endThread.interrupt();
	}
}

执行结果:

endThread interrput flag is false
endThread is run!
endThread is run!
endThread is run!
endThread is run!
endThread interrput flag is true

若方法抛出InterruptedException,线程的中断标志位会被复位成false,需要我们自己在catch里再次中断(调用interrupt方法)

Java里所有阻塞方法都会抛出InterruptedException异常

public class HasInterrputException {
	
	private static SimpleDateFormat formater = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss_SSS");
	
	private static class UseThread extends Thread{
		
		public UseThread(String name) {
			super(name);
		}
		
		@Override
		public void run() {
			String threadName = Thread.currentThread().getName();
			
			System.out.println(threadName+" interrput flag is "+isInterrupted());

			while(!isInterrupted()) {
				try {
					System.out.println("UseThread:"+formater.format(new Date()));
					Thread.sleep(3000);
				} catch (InterruptedException e) {
					System.out.println(threadName+" catch interrput flag is "
							+isInterrupted()+ " at "
							+(formater.format(new Date())));
							
					interrupt();
					
					System.out.println(threadName+" interrput flag is " +isInterrupted());

					e.printStackTrace();
				}
				System.out.println(threadName);				
			}
			System.out.println(threadName+" interrput flag is "+isInterrupted());
		}
	}

	public static void main(String[] args) throws InterruptedException {
		Thread endThread = new UseThread("HasInterrputEx");
		endThread.start();
		System.out.println("Main:"+formater.format(new Date()));
		Thread.sleep(800);
		System.out.println("Main begin interrupt thread:"+formater.format(new Date()));
		endThread.interrupt();
	}
}

执行结果:

HasInterrputEx interrput flag is false
UseThread:2019-06-22 23:04:59_236
Main:2019-06-22 23:04:59_236
Main begin interrupt thread:2019-06-22 23:05:00_038
HasInterrputEx catch interrput flag is false at 2019-06-22 23:05:00_038
HasInterrputEx interrput flag is true
java.lang.InterruptedException: sleep interrupted
	at java.lang.Thread.sleep(Native Method)
	at javaStudy.ch1.HasInterrputException$UseThread.run(HasInterrputException.java:31)
HasInterrputEx
HasInterrputEx interrput flag is true

若使用标志位的方式(volatile)控制线程运行和停止,需要注意在线程运行时如果调用了阻塞方法,那么就判断不了标志位进行停止了,要和interrupted()一起进行线程状态判断

线程生命周期

在这里插入图片描述
yield():将线程从运行转到就绪状态,这时可能cpu又选到此线程继续执行
join():线程A执行了B的join方法,线程A必须等待B执行完成了以后,线程A才能继续自己的工作

守护线程:和主线程共死,finally不能保证一定执行,所以线程执行完需要进行关闭释放资源等操作时,一定不能使用守护线程

yieldsleep方法持有的锁不会释放
wait()方法调用前,必须持有锁,调用了wait方法后,锁就会被释放,当wait方法返回(其他线程调用notifyAll唤醒),线程会重新持有锁
notify()方法调用前,必须持有锁,调用notify方法本身不会释放锁,synchronized方法执行完才会释放锁,因此一般将notify放到synchronized方法最后一行

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值