java中有几种方法可以实现多线程,java线程实现的三种方式

  java中有几种方法可以实现多线程,java线程实现的三种方式

  00-1010前言1 5.1等待()2。join () 3。睡眠()4。产量()5。总结5.1等待和加入的区别5.2等待和睡眠的区别

  在00-1010之前,我并没有太关注两者的区别和源代码讨论。

  我被后面一家公司面试,开始查漏补缺。

  00-1010使当前线程等待,直到它被唤醒,通常是被通知或中断,或者直到某个实时时间过去。

  它属于一个对象类,你可以从源代码中看到:public class Object {

  查看它的源代码,我们可以看到有三个重载的方法。详细的源代码如下:

  //第一个重载函数publicfinal void wait()抛出中断异常{ wait(0l);}//第二个重载函数public final native void wait(长超时毫秒)抛出中断异常;//第三个重载函数,public final void wait(long time out millis,int nanos)抛出中断异常{ if(time out millis 0){ throw new illegalargumentexception( time out millis值为负);} if(nanos 0 nanos 999999){ throw new IllegalArgumentException(纳秒超时值超出范围);} if (nanos 0 timeoutMillis Long。MAX _ VALUE){ time out millis;} wait(time out millis);}具体实际调用代码如下:

  如果wait函数被执行,锁将被释放,线程将在4秒内被挂起。如果您在这四秒钟内与notify()合作,就可以醒来并获得锁。不醒悟,就等别人来竞争。4秒钟后,默认锁会自动解除。

  当前线程正在Thread.wait()中等待。如果线程结束,它可以自动唤醒并自动释放锁。

  @ override public void run(){ synchronized(a){ a . wait(4000);}}

  00-1010Join是Thread类的方法。

  查一下它的源码,具体源码如下,三个重载的方法。

  //第一个重载函数,public final synchronized void join(final long millis)抛出中断异常{ if(millis 0){ if(is alive()){ final long start time=system . nano time();长延迟=毫秒;do { wait(延迟);} while(is alive()(delay=millis-time unit。纳秒.托米利斯(system . nano time()-start time))0);} } else if(millis==0){ while(is alive()){ wait(0);} } else { throw new IllegalArgumentException(超时值为负);} }//第二个重载函数/*等待这个线程死亡的最大时间是毫秒加纳秒。如果两个参数都为0,则意味着永远等待。该实现使用

  了This的循环。 等待电话以this.isAlive为条件。 当一个线程终止this。 调用notifyAll方法。 建议应用程序不要使用wait、notify或notifyAll on Thread实例。 */public final synchronized void join(long millis, int nanos)throws InterruptedException { if (millis < 0) { throw new IllegalArgumentException("timeout value is negative"); } if (nanos < 0 nanos > 999999) { throw new IllegalArgumentException( "nanosecond timeout value out of range"); } if (nanos > 0 && millis < Long.MAX_VALUE) { millis++; } join(millis);}//第三个重载函数/*等待线程死亡。 此方法的调用与调用的行为完全相同 InterruptedException—如果任何线程中断了当前线程。 当抛出此异常时,当前线程的中断状态将被清除。 */public final void join() throws InterruptedException { join(0); }主要的时间参数逻辑如下:

  小于0,抛出异常等于0,join(A),判断A是否存在,存在才执行操作。该线程执行wait(0)等待,等待A线程执行完后才可结束大于0,同上,只不过执行的是wait(long millis),等待时间结束后才可继续执行操作

 

  

3. sleep()

对比上一个wait函数

 

  sleep(long mills):让出CPU资源,但是不会释放锁资源。wait():让出CPU资源和锁资源。查看sleep函数的源码,一共有两个重载函数

  都是Thread类的函数

  

/*根据系统计时器和调度器的精度和准确性,使当前执行的线程在指定的毫秒数内处于睡眠状态(暂时停止执行)。 线程不会失去任何监视器的所有权。*/public static native void sleep(long millis) throws InterruptedException;/*导致当前执行的线程在指定的毫秒数加上指定的纳秒数(取决于系统计时器和调度器的精度和准确性)内休眠(暂时停止执行)。 线程不会失去任何监视器的所有权。 */public static void sleep(long millis, int nanos) throws InterruptedException { if (millis < 0) { throw new IllegalArgumentException("timeout value is negative"); } if (nanos < 0 nanos > 999999) { throw new IllegalArgumentException( "nanosecond timeout value out of range"); } if (nanos > 0 && millis < Long.MAX_VALUE) { millis++; } sleep(millis); }

 

  

4. yield()

查看yield()函数的源码,一个重载函数

 

  都是Thread类的函数

  向调度器暗示当前线程愿意放弃当前对处理器的使用。 调度器可以忽略这个提示。

  Yield是一种启发式尝试,旨在改善线程之间的相对进程,否则会过度使用CPU。 它的使用应该与详细的分析和基准测试相结合,以确保它实际上具有预期的效果。

  使用这种方法很少是合适的。 它可能用于调试或测试目的,在这些目的中,它可能有助于由于竞争条件而重新生成错误。 在设计并发控制构造(如java.util.concurrent.locks包中的构造)时,它可能也很有用。

  

public static native void yield();

总的来说,yield函数的功能主要是:

 

  让出CPU调度,暂停线程,但不能由用户指定时间

  只能让同优先级有执行机会

  

 

  

5. 总结

wait 暂停该线程,让出cpu,释放锁。(Object类)

 

  join暂停该线程,执行该线程之后才能回到自身的线程运行。(Thread类)

  sleep 暂停该线程,让出cpu,不释放锁。(Thread类)

  yield 暂停该线程,但是不能由用户制定,只能让同优先级有执行机会。(Thread类)

  

 

  

5.1 wait和join的区别

看完以上的源码以及逻辑代码,再讲讲两者的异同

 

  总的来说

  wait函数:让当前线程进入等待状态,wait()会与notify()和notifyAll()方法一起使用。notify为唤醒函数join函数:等待这个线程结束才能执行自已的线程。它的主要起同步作用,使线程之间的执行从并行变成串行。线程A中调用了线程B的join()方法时,线程执行过程发生改变:线程A,必须等待线程B执行完毕后,才可以继续执行下去

  共同点:

  暂停当前的线程都可以通过中断唤醒不同点在于:

  区别waitjoin类Object类Thread类目的线程间通信排序,让其串行通过同步必须要synchronized可以不用synchronized

 

  

5.2 wait和sleep的区别

wait():让出CPU资源和锁资源。

 

  sleep(long mills):让出CPU资源,但是不会释放锁资源。

  看区别,主要是看CPU的运行机制:

  它们的区别主要考虑两点:1.cpu是否继续执行、2.锁是否释放掉。

  归根到底:

  wait,notify,notifyall 都是Object对象的方法,是一起使用的,用于锁机制,所以会释放锁

  而sleep是Thread类,跟锁没关系,不会释放锁

  但是两者都会让出cpu资源

  以上就是Java四个线程常用函数超全使用详解的详细内容,更多关于Java线程函数的资料请关注盛行IT其它相关文章!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: