线程 Thread

程序与进程

程序:一段静态的代码。

进程:程序的一次动态执行过程,它对应从代码加载、执行到执行完毕的一个完整过程。

进程也称任务,支持多个进程同时执行的OS就被称为多进程OS或多任务OS

 

进程与线程

在一个程序内部也可以实现多个任务并发执行,其中每个任务称为线程。

线程是比进程更小的执行单位,它是在一个进程中独立的控制流,即程序内部的控制流。

特点:线程不能独立运行,必须依赖于进程,在进程中运行。

每个程序至少有一个线程称为主线程

单线程:只有一条线程的进程称为单线程

多线程:有不止一个线程的进程称为多线程

 

开启多线程的优点和缺点

提高界面程序响应速度。通过使用线程,可以将需要大量时间完成的流程在后台启动单独的线程完成,提高前台界面的相应速度。

充分利用系统资源,提高效率。通过在一个程序内部同时执行多个流程,可以充分利用CPU等系统资源,从而最大限度的发挥硬件的性能。

当程序中的线程数量比较多时,系统将花费大量的时间进行线程的切换,这反而会降低程序的执行效率。但是,相对于优势来说,劣势还是很有限的,所以现在的项目开发中,多线程编程技术得到了广泛的应用

 

多线程的实现方式

在实际实现线程时,Java语言提供了三种实现方式:

继承Thread

实现Runnable接口

使用TimerTimerTask组合

 

继承Thread类实现多线程。

       MyThread  tt1 = new MyThread ();

       //启动线程

       tt1.start();

       try{

              for(inti = 0;i < 5;i++){

                     //延时1

                     Thread.sleep(1000);

                     System.out.println("Main:"+ i);

              }

       }catch(Exceptione){}

 

注意:

线程的特性:随机性,系统在执行多线程程序时只保证线程是交替执行的,至于哪个线程先执行哪个线程后执行,则无法获得保证,需要书写专门的代码才可以保证执行的顺序。

对于同一个线程类,也可以启动多个线程。
Thread2 t2 = new Thread2();   t2.start();
Thread2 t3 = new Thread2();   t3.start();

同一个线程不能启动两次,例如 
Thread2 t2 = new Thread2();
t2.start();          t2.start();   //
错误

当自定义线程中的run方法执行完成以后,则自定义线程自然死亡。而对于系统线程来说,只有当main方法执行结束,而且启动的其它线程都结束以后,才会结束。当系统线程执行结束以后,程序的执行才真正结束。

 

实现Runable接口

多线程对象实现java.lang.Runnable接口并且在该类中重写Runnable接口的run方法。

好处:实现Runable接口的方法避免了单继承的局限性。

 

线程的生命周期

       新建(start())——就绪(cpu可用)——运行——死亡

                                                 阻塞   )——死亡

线程的优先级

把线程从就绪状态进入运行状态的过程叫做线程调度。负责调度工作的机构叫做调度管理器

优先级:线程的优先级的取值范围是1~10
MAX_PRIORITY    =    10
NORM_PRIORITY   =   5
MIN_PRIORITY    =    1

得到或修改线程的优先级
public final int getPriority();
public final void setPriority(int newPriority);

 

常用方法

void run()   //创建该类的子类时必须实现的方法

void start() //开启线程的方法

static voidsleep(long t) //释放CPU的执行权,不释放锁

static voidsleep(long millis,int nanos)

final voidwait()//释放CPU的执行权,释放锁

final voidnotify()

static voidyied()//可以对当前线程进行临时暂停(让线程将资源释放出来)

public finalvoid stop()//结束线程,但由于安全的原因过时

 

为什么需要线程同步
线程间共享代码和数据可以节省系统开销,提高程序运行效率,但同时也导致了数据的访问冲突问题,如何实现线程间的有机交互、并确保共享资源在某些关键时段只能被一个线程访问,即所谓的线程同步”(Synchronization)就变得至关重要。

临界资源
多个线程间共享的数据称为临界资源(Critical Resource),由于是线程调度器负责线程的调度,程序员无法精确控制多线程的交替顺序。因此,多线程对临界资源的访问有时会导致数据的不一致行。

 

 

互斥锁

每个对象都对应于一个可称为互斥锁的标记,这个标记用来保证在任一时刻,只能有一个线程访问该对象。

Java对象默认是可以被多个线程共用的,只是在需要时才启动互斥锁机制,成为专用对象。

关键字synchronized用来与对象的互斥锁联系

当某个对象用synchronized修饰时,表明该对象已启动互斥锁机制,在任一时刻只能由一个线程访问,即使该线程出现堵塞,该对象的被锁定状态也不会解除,其他线程任不能访问该对象。

 

线程同步通信
为避免死锁,就应该让线程在进入阻塞状态时尽量释放其锁定的资源,以为其他的线程提供运行的机会,Object类中定义了几个有用的方法:wait()notify()notifyAll()

wait():被锁定的对象可以调用wait()方法,这将导致当前线程被阻塞并释放该对象的互斥锁,即解除了wait()方法当前对象的锁定状态,其他的线程就有机会访问该对象。

notify():唤醒调用wait()方法后被阻塞的线程。每次运行该方法只能唤醒一个线程。

notifyAll():唤醒所有调用wait()方法被阻塞的线程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值