多线程理解

本文详细介绍了Java中实现多线程的两种方式:继承Thread类和实现Runnable接口。重点讨论了run()与start()的区别,强调start()会自动调用run()并启动线程。此外,文章还探讨了线程同步的关键字synchronized,以及sleep()方法的作用。通过实例展示了线程优先级的设置和调度,包括yield()、join()、wait()、notify()和notifyAll()等线程控制方法。最后,文章提醒读者main方法也是一个线程,并建议避免使用已废弃的suspend()和resume()方法,以防止死锁。

实现线程的方式有两种:

1、继承java.lang.Thread,并重写它的run()方法

2、实现java.lang.Runnable接口,实现它的run()方法,接口中就一个方法run()

一、run()和start()

stat() 用于自动调用run()

其实Thread中的run方法调用的是Runnable接口的run方法。 Thread和Runnable都实现了run方法,这种操作模式其实就是代理模式。关于代理模式

https://blog.youkuaiyun.com/zhangzeyuaaa/article/details/41869221

        那么:为什么我们不能直接调用run()方法呢?

        我的理解是:线程的运行需要本地操作系统的支持。

        如果你查看start的源代码的时候,会发现:

run() 的访问控制符必须是public,返回值必须是void

二、有了synchronized关键字,多线程程序的运行结果将变得可以控制

synchronized使同一个对象的多个线程

三、sleep()

方法会使当前的线程暂停执行一定时间(给其它线程运行机会)。

Runnable r = new ThreadTest();

Thread t1 = new Thread(r, "t1_name");

Thread t2 = new Thread(r, "t2_name");

t1.setPriority(Thread.MAX_PRIORITY);

t2.setPriority(Thread.MIN_PRIORITY);

t1.start();

t2.start();

t1被设置了最高的优先级,t2被设置了最低的优先级。t1不执行完,t2就没有机会执行。

总结一下吧:

实现Runnable接口比继承Thread类所具有的优势:

1):适合多个相同的程序代码的线程去处理同一个资源

2):可以避免java中的单继承的限制

3):增加程序的健壮性,代码可以被多个线程共享,代码和数据独立。

提醒一下大家:main方法其实也是一个线程。在java中所以的线程都是同时启动的,至于什么时候,哪个先执行,完全看谁先得到CPU的资源。

Thread.yield() 方法,暂停当前正在执行的线程对象,让当前运行线程回到可运行状态,以允许具有相同优先级的其他线程获得运行机会。

线程调度

线程的调度

1、调整线程优先级:Java线程有优先级,优先级高的线程会获得较多的运行机会。

Java线程的优先级用整数表示,取值范围是1~10,Thread类有以下三个静态常量:

static int MAX_PRIORITY

          线程可以具有的最高优先级,取值为10。

static int MIN_PRIORITY

          线程可以具有的最低优先级,取值为1。

static int NORM_PRIORITY

          分配给线程的默认优先级,取值为5。

Thread类的setPriority()和getPriority()方法分别用来设置和获取线程的优先级。

每个线程都有默认的优先级。主线程的默认优先级为Thread.NORM_PRIORITY。

线程的优先级有继承关系,比如A线程中创建了B线程,那么B将和A具有相同的优先级。

JVM提供了10个线程优先级,但与常见的操作系统都不能很好的映射。如果希望程序能移植到各个操作系统中,应该仅仅使用Thread类有以下三个静态常量作为优先级,这样能保证同样的优先级采用了同样的调度方式。

2、线程睡眠:Thread.sleep(long millis)方法,使线程转到阻塞状态。millis参数设定睡眠的时间,以毫秒为单位。当睡眠结束后,就转为就绪(Runnable)状态。sleep()平台移植性好。

3、线程等待:Object类中的wait()方法,导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 唤醒方法。这个两个唤醒方法也是Object类中的方法,行为等价于调用 wait(0) 一样。

4、线程让步:Thread.yield() 方法,暂停当前正在执行的线程对象,把执行机会让给相同或者更高优先级的线程。

5、线程加入:join()方法,等待其他线程终止。在当前线程中调用另一个线程的join()方法,则当前线程转入阻塞状态,直到另一个进程运行结束,当前线程再由阻塞转为就绪状态。

6、线程唤醒:Object类中的notify()方法,唤醒在此对象监视器上等待的单个线程。如果所有线程都在此对象上等待,则会选择唤醒其中一个线程。选择是任意性的,并在对实现做出决定时发生。线程通过调用其中一个 wait 方法,在对象的监视器上等待。 直到当前的线程放弃此对象上的锁定,才能继续执行被唤醒的线程。被唤醒的线程将以常规方式与在该对象上主动同步的其他所有线程进行竞争;例如,唤醒的线程在作为锁定此对象的下一个线程方面没有可靠的特权或劣势。类似的方法还有一个notifyAll(),唤醒在此对象监视器上等待的所有线程。

 注意:Thread中suspend()和resume()两个方法在JDK1.5中已经废除,不再介绍。因为有死锁倾向。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值