多线程-线程状态与创建

 状态

线程生命周期不可逆:一旦进入 Runnable 状态就不能回到 New 状态;一旦被终止就不可能再有任何状态的变化。所以一个线程只能有一次 New 和 Terminated 状态,只有处于中间状态才可以相互转换。


创建

准确的讲,创建线程只有一种方式那就是构造Thread类而实现线程的执行单元有两种方式

实现Runnable接口的run方法,并把Runnable实例传给Thread类

实现 runnable 接口

public class MyRunnable implements Runnable {
  @Override
  public void run() {
    try {
      Thread.sleep(TimeUnit.SECONDS.toMillis(50));
      System.out.println("dddd");
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
    System.out.println(Thread.currentThread().getName());
  }
  public static void main(String[] args) {
    new Thread(new MyRunnable()).start();
    new Thread(new MyRunnable()).start();
  }
}

 匿名内部类

new Thread(new Runnable() {
    @Override
    public void run() {
     for (int i = 0; i < 100; i++) {
      System.out.println(i);
     }
    }
   }).start();

lambda表达式

Runnable race2 = () -> System.out.println("Hello world !");
new Thread(race2).start();

重写Thread的run方法(继承Thread类)

 class demo extends Thread {
 public void run() {
   for (int i = 0; i < 100; i++) {
    System.out.println("---------------" + i);
   }
 }
}
new demo().start();

定时器

Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
  @Override
  public void run() {
   System.out.println("dd");
  }
},10,10);

Callable和Future

  1. Future接口定义了操作异步任务执行一些方法,如获取异步任务的执行结果、取消任务的执行、判断任务是否被取消、判断任务执行是否完毕等。
  2. Callable接口中定义了需要有返回的任务需要实现的方法
  3. Future是一个存储器,它存储了call这个任务的结果,而这个任务的执行时间是无法提前确定的

Runnable的缺陷

  • 不能返回一个返回值
  • 也不能抛出checked Exception

FutureTask

  1. FutureTask是一种包装器,可以把Callable转化成Future和Runnable,它同时实现二者的接口
  2. 所以它既可以作为Runnable被线程执行,又可以作为Future 得到Callable的返回值
  3. 把Callable实例当作参数,生成FutureTask的对象,然后把这个对象当作一个Runnable对象,用线程池或另起线程去执行这个Runnable对象,最后通过FutureTask获取刚才执行的结果

Callable<Integer> callable = () -> {
    System.out.println("dd");
    return 1;
};
FutureTask<Integer> futureTask = new FutureTask<>(callable);
Thread thread = new Thread(futureTask);
thread.start();
Integer integer = futureTask.get();
System.out.println(integer);

future 方法

get

  1. 任务正常完成∶get方法会立刻返回结果
  2. 任务尚未完成(任务还没开始或进行中)∶get将阻塞并直到任务完成。
  3. 任务执行过程中抛出Exception∶get方法会抛出ExecutionException∶这里的抛出异常,是call执行时产生的那个异常,看到这个异常类型是java.util.concurrent.ExecutionException。不论call执行时抛出的异常类型是什么,最后get方法抛出的异常类型都是ExecutionException。
  4. 任务被取消∶get方法会抛出CancellationException

get(long timeout, TimeUnit unit)

  • 如果call在规定时间内完成了任务,那么就会正常获取到返回值;而如果再指定时间内没有计算出结果,那么就会抛出TimeoutException
  • 超时不获取,任务需取消

isDone()轮询

轮询的方式会耗费无谓的CPU资源,而且也不见得能及时地得到计算结果.

如果想要异步获取结果,通常都会以轮询的方式去获取结果 ,尽量不要阻塞

@Test
public void isDone() throws ExecutionException, InterruptedException {
	FutureTask<String> futureTask = new FutureTask<>(() -> {
		System.out.println("-----come in FutureTask");
		try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); }
		return ""+ThreadLocalRandom.current().nextInt(100);
	});

	new Thread(futureTask,"t1").start();

	System.out.println(Thread.currentThread().getName()+"\t"+"线程完成任务");

	/**
         * 用于阻塞式获取结果,如果想要异步获取结果,通常都会以轮询的方式去获取结果
         */
	while(true)
	{
		if (futureTask.isDone())
		{
			System.out.println(futureTask.get());
			break;
		}
	}
}
}

总结

  1. 不见不散
  2. 过时不候
  3. 轮询
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值