Java线程

来源:互联网 发布:golang for 编辑:程序博客网 时间:2024/06/07 17:39

线程的五种状态:

1.new(新建):新建一个线程对象

    有三种方法:

      ①  继承Thread类实现多线程,但Thread本质上也是实现了Runnable接口的一个实例,它代表一个线程的实例

  1. public class MyThread extends Thread {  
  2.   public void run() {  
  3.    System.out.println("MyThread.run()");  
  4.   }  
  5. }  

      实现Runnable接口方式实现多线程,如果自己的类已经extends另一个类,就无法直接extends Thread,此时,必须实现一个Runnable接口,如下


  1. public class MyThread extends OtherClass implements Runnable {  
  2.   public void run() {  
  3.    System.out.println("MyThread.run()");  
  4.   }  
  5. } 
   ③使用ExecutorService、Callable、Future实现有返回结果的多线程。ExecutorService、Callable、Future这个对象实际上都是属于Executor框架中的功能类。

2.runnable(可运行):线程对象创建后,其他线程调用了该对象的start()方法,等待被线程调度选中,获取CPU限权
  1. MyThread myThread1 = new MyThread();  
  2. MyThread myThread2 = new MyThread();  
  3. myThread1.start();  
  4. myThread2.start();

3.running(运行):可运行状态的的线程获得了cpu的时间片,执行程序代码

4.block(阻塞):阻塞状态是指线程因某种原因放弃了CPU限权,也让出timeslite,暂时停止运行,阻塞情况分三种:
 1>等待阻塞:运行中的线程执行wait()方法,JVM会把该线程放入等待队列中
  2>同步阻塞:运行中的线程在获取对象的同步锁时,若该同步锁被别的线程占用,JVM会把该线程放入锁池里
  3>其他阻塞:执行sleep()方法
              线程调用一个在I/O上被阻塞的操作,即该操作在输入输出操作完成之前不会返回到它的调用者

5.死亡状态(Dead):

   有两个原因会导致线程死亡:
   1> run方法正常退出而自然死亡,
   2>一个未捕获的异常终止了run方法而使线程猝死。
   为了确定线程在当前是否存活着(就是要么是可运行的,要么是被阻塞了),需要使用isAlive方法。如果是可运行       或被阻塞,这个方法返回true; 如果线程仍旧是new状态且不是可运行的, 或者线程死亡了,则返回false


wait()与sleep方法的区别:

1.wait()来自Object类,sleep()来自Theard类

2.sleep没有释放锁,不会让出系统资源,它可以用时间指定使它自动唤醒过来,如果时间不到,只能用interrupt()强      行打断。

   wait释放了锁,让出系统资源敏感词线程可用,等待敏感词线程调用notify/notifyAll唤醒等待池中的线程。

3.wait,notify,notifyAll只能在同步块或同步方法中使用

    Synchronized(x){        x.wait();        x.notify();    }

   sleep可以在任何地方使用

4.wait不用捕获异常,sleep必须捕获异常


线程安全和线程不安全:

非线程安全:当线程A获取一条数据,准备修改时,B线程进来了,并且把A这条数据删除了,这时A线程再执行就会报错。

线程安全:在A线程修改这条数据时,给它加一个锁(监视器),B进来时,发现数据已经上了锁,就会在线程池等待,等待A线程释放数据后,再对数据进行操作,这样防止脏数据产生。




原创粉丝点击