Thread类

来源:互联网 发布:三菱plc仿真软件汉化 编辑:程序博客网 时间:2024/04/30 02:32

Thread的run方法就不多说了;

一.interrupt()方法

interrupt()不会中断一个正在运行的线程。但是会改变状态,也就是isInterruped()方法返回true;(如果后边再遇到sleep或wait,join,则会抛出中断异常);这一方法实际上完成的是,在线程受到阻塞时抛出一个中断信号,这样线程就得以退出阻塞的状态。

也就是说,线程被Object.wait,Thread.join和Thread.sleep 三种方法之一阻塞,接收到中断信号,会抛出中断异常(interruptedException),从而

提早的终结被阻塞状态;

2. isInterrupted()方法返回中断状态; interrupted()方法返回中断状态,并且重置状态;

二. wait, sleep,yield,join 阻塞方法说明;

1.sleep(1000) 线程的静态方法, 使当前线程就如停滞状态,同时sleep函数不会释放锁;

作用: sleep可使优先级低的线程得到执行的机会,当然也可以让同优先级和高优先级的线程有执行的机会;

2.yield()   线程让步方法,同样也是线程的静态方法

当线程在运行中执行了Thread类的yield()静态方法,如果此时具有相同优先级的其他线程处于就绪状态,yield()方法将把当前运行的线程放到可运行池中并使另一个线程运行。如果没有相同优先级的可运行进程,yield()方法什么都不做,同样不会释放锁资源;

sleep和yield的区别在于, sleep可以使优先级低的线程得到执行的机会,  而yield只能使同优先级或更高优先级的线程有执行的机会.

网上摘的一段:

yield()没有参数

sleep 方法使当前运行中的线程睡眠一段时间,进入不可以运行状态,这段时间的长短是由程序设定的,yield方法使当前线程让出CPU占有权,但让出的时间是不可设定的。

yield()也不会释放锁标志。

实际上,yield()方法对应了如下操作;先检测当前是否有相同优先级的线程处于同可运行状态,如有,则把CPU的占有权交给次线程,否则继续运行原来的线程,所以yield()方法称为“退让”,它把运行机会让给了同等级的其他线程。

sleep 方法允许较低优先级的线程获得运行机会,但yield()方法执行时,当前线程仍处在可运行状态,所以不可能让出较低优先级的线程此时获取CPU占有权。在一个运行系统中,如果较高优先级的线程没有调用sleep方法,也没有受到I/O阻塞,那么较低优先级线程只能等待所有较高优先级的线程运行结束,方可有机会运行。

yield()只是使当前线程重新回到可执行状态,所有执行yield()的线程有可能在进入到可执行状态后马上又被执行,所以yield()方法只能使同优先级的线程有执行的机会。


3.wait notify() notifyAll();    他们是Object对象的方法;

这三个方法用于协调多个线程对共享数据的存取,所以必须在synchronized语句块内使用。synchronized关键字用于保护共享数据,阻止其他线程对共享数据的存取,但是这样程序的流程就很不灵活了,如何才能在当前线程还没退出synchronized数据块时让其他线程也有机会访问共享数据呢?此时就用这三个方法来灵活控制。

wait()方法使当前线程暂停执行并释放对象锁标示,让其他线程可以进入synchronized数据块,当前线程被放入对象等待池中。当调用notify()方法后,将从对象的等待池中移走一个任意的线程并放到锁标志等待池中,只有锁标志等待池中线程能够获取锁标志;如果锁标志等待池中没有线程,则notify()不起作用。

notifyAll()则从对象等待池中移走所有等待那个对象的线程并放到锁标志等待池中。

wait notify() notifyAll()必须在同步代码块中用;

否则则会抛出java.lang.IllegalMonitorStateException 异常;

注意:wait用interrupt()方法中断,是先获得锁然后再抛出异常;

4.join()方法:

他是线程中的方法; 意思是让另一个线程等待掉用了join()的线程执行完毕再执行;

我们可以看一下Thread中join源码:

    public final synchronized void join(long millis)    throws InterruptedException {        long base = System.currentTimeMillis();        long now = 0;        if (millis < 0) {            throw new IllegalArgumentException("timeout value is negative");        }        if (millis == 0) {            while (isAlive()) {                wait(0);            }        } else {            while (isAlive()) {                long delay = millis - now;                if (delay <= 0) {                    break;                }                wait(delay);                now = System.currentTimeMillis() - base;            }        }    }

当millis安苏是0的时候:进入 while(isAlive())这个循环;也就是让获得这个线程锁的线程阻塞住,直到当前线程结束,然后唤醒阻塞线程; 如: A,B两个线程: A , B;  A线程调用 B.join(); 则 A拿到了B对象的锁,等待B结束;

有一个问题就是线程B,执行结束,是如何唤醒A的在代码中并没有看到,估计Thead类底层做了类似notify的操作;

由于join也是wait实现,因此用interrupt()方法中断join()阻塞的线程,也是要先获得锁,然后再抛出中断异常;



0 0