java多线程学习记录

来源:互联网 发布:东方不败网络歌手 编辑:程序博客网 时间:2024/05/16 08:40
  • “Thread extends Object implements Runnable”

  • 继承 Extend Thread,重写run方法

public class ExtThread2 extends Thread {    private int count = 1;    @Override    public void run() {    }}  Thread th1 = new ExtThread2("name");  th1.start();
  • 实现implements Runnable,实现run方法,创建实例作为Thread构造器的参数;用同一个Runnable实例创建Thread时,可以共享同一个变量。
public class ExtThread1 implements Runnable {    private int count = 1;    public void run() {}}Runnable my = new ExtThread1();Thread th1 = new Thread(my,"name");th1.start();
  • Callable接口定义了call()方法,Future接口定义了几个方法来控制关联的Callable任务;Future的实现类Futuretask既实现了Future,也实现了Runnable
// 该接口有泛型限制,与返回值类型相同public class CallThread implements Callable<Integer>{    public Integer call() {return }}Callable th3 = new CallThread();FutureTask<Integer> task = new FutureTask<Integer>(th3);// 因为FutureTask实现了Runnable,所以可以传递给Threadnew Thread(task,"callableThread").start();try{// 同时还可以利用Future来监控任务的执行情况// 如果只开启了一个线程,然后就使用get则,后面的线程要等待该线程执行完才会继续向下执行// 为了避免阻塞,可以先把所有的线程启动,然后再获取对应的结果,这样就不会阻塞    System.out.println(task.get());} catch (Exception e) {    e.printStackTrace();}

总结:创建线程的三种方式对比

Runnable/Callable
- 线程类还可以继承其他类
- 多个线程可以共享同一个target对象
- Callable还有返回值

线程的生命周期

  • 新建(new)、就绪(runnable)、运行(running)、阻塞(blocked)、死亡(Dead)
  • join线程:在一个线程里面调用另外一个线程,并等待其执行完毕
  • daemon后台线程:前台线程死亡后,JVM会通知后台线程死亡
  • sleep:暂停当前正在执行的线程,一直阻塞到指定时间,然后线程才变成就绪状态(其他线程继续)
  • yield:也是暂停线程,但是会把线程转变成就绪状态(不阻塞),所以线程可能随时有被调度,这种不保险,没有意义。

线程同步

  • synchronized用来修饰方法、代码块(对this对象,或者普通的对象进行监视)(加锁–放锁)
  • notify/notifyAll/wait用于在synchronized代码块中线程间的通信
  • notify用于唤醒该同步监视器上的线程。说明:“只是唤醒wait的线程,当前线程会继续执行下去,被唤醒的线程也不一定是立马就执行”;被唤醒的线程执行的时候,是在wait处继续向下执行,不是重新执行;被唤醒后就可以抢占资源了;从上面可以看出,notify必须和wait搭配使用才有意义
  • wait用于将当前线程阻塞,但需要把占用的锁先释放掉,只有被重新唤醒才会继续执行,否则会一直阻塞;sleep同样会阻塞,但只会阻塞固定的时间,而且阻塞的时候会继续占用锁。
0 0