并发3-Thread类和API

1.Thread类详解:

    无论是通过继承Thread还是实现Runnable接口来实现多线程编程,都离不开Thread。

    Thread译为线程,线程有以下几种状态,接下来我会按照Thread类中的方法来逐一讲解。

    

    1.Thread t = new Thread()仅仅只是创建了线程,并没有为线程分配任何资源

    2.start()方法用来启动线程,为相应地线程分配资源,分配到资源才能参与到竞争CPU的过程中

      run():当start()启动一个线程后,线程一直等待直到获得了CPU执行时间,就进入run方法体

    3.sleep()让线程休眠,主动让出CPU,但是不会释放锁,休眠时间满后,不一定立即得到执行,还需要重新参与竞争排队

 
 
  1. public class MyThread{

  2. private int i = 10;

  3. public Object lock = new Object();

  4. public static void main(String[] args) {

  5. MyThread mh = new MyThread();

  6. ThreadTest tt = mh.new ThreadTest();

  7. ThreadTest tt2 = mh.new ThreadTest();

  8. tt.start();

  9. tt2.start();

  10. }

  11. class ThreadTest extends Thread{

  12. @Override

  13. public void run() {

  14. synchronized (lock) {

  15. i++;

  16. System.out.println("i:" + i);

  17. try {

  18. System.out.println(Thread.currentThread().getId()+"睡眠开始");

  19. Thread.currentThread().sleep(1000);//睡眠并不释放锁

  20. } catch (Exception e) {

  21. }finally {

  22. System.out.println(Thread.currentThread().getId()+"睡眠结束");

  23. }

  24. i++;

  25. System.out.println("i:" + i);

  26. }

  27. }

  28. }

  29. }

   输出:

 
 
  1. i:11

  2. 10睡眠开始

  3. 10睡眠结束

  4. i:12

  5. i:13

  6. 11睡眠开始

  7. 11睡眠结束

  8. i:14


    4.yield()使线程让出CPU去执行相同优先级的其他程序,但是不会释放锁,(内部还是sleep)执行yield()之后该线程直接再次参与竞争,而不进行阻塞等待。


    5.A线程的run()中调用了B线程的join(),则A线程等待B线程执行完之后,再继续执行,实际上调用了Object类中的wait()方法,会释放锁

 
 
  1. /**
  2. * Created by liuyl on 15/11/27.
  3. *  调用了thread.join需要等到thread的run方法执行完毕,主线程才可以继续执行
  4. */
  5. public class ThreadJoin {
  6.    public static void main(String[] args) throws IOException {
  7.        System.out.println("进入线程"+Thread.currentThread().getName());
  8.        ThreadJoin test = new ThreadJoin();
  9.        MyThread thread1 = test.new MyThread();
  10.        thread1.start();
  11.        try {
  12.            System.out.println("线程"+Thread.currentThread().getName()+"等待");
  13.            thread1.join();
  14.            System.out.println("线程"+Thread.currentThread().getName()+"继续执行");
  15.        } catch (InterruptedException e) {
  16.            // TODO Auto-generated catch block
  17.            e.printStackTrace();
  18.        }
  19.    }
  20.    class MyThread extends Thread{
  21.        @Override
  22.        public void run() {
  23.            System.out.println("进入线程"+Thread.currentThread().getName());
  24.            try {
  25.                Thread.currentThread().sleep(5000);
  26.            } catch (InterruptedException e) {
  27.                // TODO: handle exception
  28.            }
  29.            System.out.println("线程"+Thread.currentThread().getName()+"执行完毕");
  30.        }
  31.    }
  32. }

    输出结果:

 
 
  1. 进入线程main

  2. 线程main等待

  3. 进入线程Thread-0

  4. 线程Thread-0执行完毕

  5. 线程main继续执行


    join中调用了wait()方法:thread1.join()调用了wait方法

    其中wait()在Jdk中的源码为:

 
 
  1. public final native void wait(long timeout) throws InterruptedException;

    wait为native方法

    


      6.interrupt()使得处于阻塞状态的线程抛出一个异常,也就是说,它可以中断并且只能中断一个处于阻塞状态的线程

 
 
  1. public class MyThread{

  2. public static void main(String[] args) {

  3. MyThread mh = new MyThread();

  4. ThreadTest tt = mh.new ThreadTest();

  5. tt.start();

  6. try {

  7. Thread.currentThread().sleep(2000);

  8. } catch (InterruptedException e) {

  9. e.printStackTrace();

  10. }

  11. tt.interrupt();

  12. }

  13. class ThreadTest extends Thread{

  14. @Override

  15. public void run() {

  16. try {

  17. System.out.println("子线程睡眠开始");

  18. Thread.currentThread().sleep(10000);

  19. System.out.println("子线程睡眠结束");

  20. } catch (InterruptedException e) {

  21. System.out.println("子线程获取到中断");

  22. }

  23. System.out.println("run执行完毕");

  24. }

  25. }

  26. }

    输出结果:

 
 
  1. 子线程睡眠开始
  2. 子线程获取到中断
  3. run执行完毕


    7.开发中一般不使用interrupt()而在类中增加isStop属性来标志是否结束while循环

 
 
  1. class MyThread extends Thread{

  2.        private volatile boolean isStop = false;

  3.        @Override

  4.        public void run() {

  5.            int i = 0;

  6.            while(!isStop){

  7.                i++;

  8.            }

  9.        }

  10.        

  11.        public void setStop(boolean stop){

  12.            this.isStop = stop;

  13.        }

  14.    }

    那么就可以在外面通过调用setStop方法来终止while循环    


2.上下文切换:

    对于两个线程来说,如果是单核CPU的计算机,一个时刻只能运行一个线程,线程切换指的是线程A中断释放出CPU转让CPU资源给线程B运行。

    对于线程切换,需要保存线程的上下文,以方便线程B执行完释放CPU给线程A时,线程A能继续从刚才保存的断点执行。

    所以CPU需要记录,线程执行到哪里(程序计数器),线程挂起时的变量(CPU寄存器状态)等


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值