1、 继承 Thread 类 启动线程步骤: a、定义Thread类的子类(继承Thread类),并重写该类的run()方法,该方法的方法体就是线程需要完成的任务,run()方法也称为线程执行体
b、创建Thread子类的实例,也就是创建了线程对象(使用new创建的对象) c、启动线程,即调用线程的start()方法 注:start ()是真正的启用了线程 run() 只是thread类的一个方法这里我将b、c两个步骤合在一起了 2、 实现Runnable接口 启动线程步骤 1、实现runnable 重写run 方法
2、不是Thread类无法直接调用start()方法,所以需要先进行转换在调用 转换步骤: a、先创建对象(这里是ThreadDemo2)直接使用new即可 b、创建完对象之后再将其转换成Thread类,这样就可以调用start()方法启动线程
1、继承了 Thread 的类不适合多个线程共享资源 2、而实现了 Runnable 接口可以方便地实现资源共享 简单的理解是资源是否共享 这里的实现Runnable 接口会出现资源不同步问题,在下方的同步中说明
1、返回线程名称 Thread.currentThread().getName() 2、设置线程优先级
t1.setPriority(Thread.MIN_PRIORITY); //低 t2.setPriority(Thread.MAX_PRIORITY); //高 t3.setPriority(Thread.NORM_PRIORITY); //中3、使目前的线程休眠
try{ Thread.sleep(1000); }catch(Exception e){ e.printStackTrace(); }4、暂停目前的线程,运行其他线程
Thread.currentThread().yield();在上方提到过实现Runnable接口是资源共享但是会出现资源不同步问题 1、同步锁
Synchronized(同步对象){ }2、死锁 多个线程共享同一资源需要进行同步,以保证资源操作的完整性,但过多的同步可能产生死锁 出现死锁问题需要满足以下条件:
互斥条件:一个资源每次只能被一个线程使用。请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。不可剥夺条件:进程已获得的资源,在未使用完之前,不能强行剥夺。循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。只要破坏死锁 4 个必要条件之一中的任何一个,死锁问题就能被解决。 解决方案:打破互斥条件,我们需要允许进程同时访问某些资源,这种方法受制于实际场景,不太容易实现条件;打破不可抢占条件,这样需要允许进程强行从占有者那里夺取某些资源,或者简单一点理解,占有资源的进程不能再申请占有其他资源,必须释放手上的资源之后才能发起申请,这个其实也很难找到适用场景;进程在运行前申请得到所有的资源,否则该进程不能进入准备执行状态。这个方法看似有点用处,但是它的缺点是可能导致资源利用率和进程并发性降低;避免出现资源申请环路,即对资源事先分类编号,按号分配。这种方式可以有效提高资源的利用率和系统吞吐量,但是增加了系统开销,增大了进程对资源的占用时间。上述案例只需更改一下调用顺序或条件即可解决。