多线程

    技术2022-05-19  21

    线程和进程进程:独立执行的一个程序称为进程。线程:进程中的一个单一的连续控制流程,不能独立运行,一个进程可以拥有一个或多个线程,当一个进程拥有多个线程的时候称之为多线程。

    单线程程序与多线程程序单线程程序:程序只有一个线程顺序执行。多线程程序:程序有多个线程并发执行。

    Java对多线程的支持Java在语言级提供了对多线程程序设计的支持。实现多线程程序的两种方式:    (1)从Thread类继承;    (2)实现Runnable接口。

    继承Thread类的实现方式:class MyThread extends Thread{ public void run(){  System.out.println("线程运行了."); }}public class MultiThread { public static void main(String[] args){  MyThread mt=new MyThread();  //生成一个线程的对象  mt.start();  //用start方法启动线程  System.out.println("main方法运行了."); }}

    实现Runnable接口的实现方式:class MyThread implements Runnable{ public void run(){  System.out.println("线程运行了."); }}public class MultiThread { public static void main(String[] args){  MyThread mt=new MyThread();  //生成一个线程的对象  Thread t=new Thread(mt);  //还是需要用Thread类创建线程  t.start();  //启动线程  System.out.println("main方法运行了."); }}

    两种实现方式的比较继承Thread类,该类将不能继承其它类,每个线程拥有自己的对象。     MyThread mt1=new MyThread();     MyThread mt2=new MyThread();     t1.start();     t2.start();

    实现Runnable接口,该类还能继承其它类,每个线程可以共享一个对象。     MyThread mt=new MyThread(); Thread t1=new Thread(mt); Thread t2=new Thread(mt); t1.start(); t2.start();守护线程 通过前面的例子可以知道,主线程和其他线程的执行是并行的,互不干扰的,即一个线程的终止和其他线程没有关系,当你想让其他线程在主线程结束的时候也跟着结束,可以将该线程设置为守护线程。     MyThread mt=new MyThread(); Thread t1=new Thread(mt); t1.setDaemon(true);    //使用setDaemon方法将线程设为守护线程 //start方法必须在setDaemon方法后面调用,否则设置无效     t1.start();         System.out.println(t1.isDaemon());    //查看该线程是否为守护线程

    join()和yield()如果有一个线程A正在运行,你希望插入另一个线程并要求插入的线程执行完毕之后再执行线程A,可以使用join()方法来完成这个需求,就好像你手头上正有一个工作在进行,老板插入一个工作要求你先作好,然后再进行原先的工作。

    如果有两个线程A和B,当A调用了yield()方法后,线程A将放弃当前的执行机会,让线程B执行,直到线程A下次有机会的时候再执行。

    线程常用方法

    方法          说明start()  启动线程isAlive()  线程是否还活着(Runnable、Running、Blocked)static?void sleep(long?m) 使当前的线程睡m个毫秒getPriority () 得到线程的优先级setPriority (int?newP)  设置线程的优先级static?void yield()  让出CPU,当前线程进入就绪等待队列wait() 等待某个信号或事件,进入blocked状态,notify()、notityAll() 唤醒某个执行了wait()的线程;                        唤醒所有执行了wait()的线程

    线程的状态创建状态(New)  执行下列语句时,线程就处于创建状态: MyThread mt = new MyThread ( ); 当一个线程处于创建状态时,它仅仅是一个空的线程对象,系统   不为它分配资源。

     2.可运行状态( Runnable )   mt.start( );当一个线程处于可运行状态时,系统为这个线程分配了它需的系     统资源,安排其运行并调用线程运行方法,这样就使得该线程处于可运行( Runnable )状态。需要注意的是这一状态并不是运行中状态(Running ),因为线程也许实际上并未真正运行。由于很多计算机都是单处理器的,所以要在同一时刻运行所有的处于可运行状态的线程是不可能的,Java的运行系统必须实现调度来保证这些线程共享处理器。3.阻塞状态(Not Runnable)  进入不可运行状态的原因有如下几条:   1) 调用了sleep()方法;       2) 为等候一个条件变量,线程调用wait()方法;   3) 输入输出流中发生线程阻塞;  因为某种原因(输入/输出、等待消息或其它阻塞情况),系统不能执行线程的状态。这时即使处理器空闲,也不能执行该线程。

    4. 死亡状态(Dead) 线程的终止一般可通过两种方法实现:自然撤消(线程执行完)或是被停止(调用stop()方法)。目前不推荐通过调用stop()来终止线程的执行(随意的stop会导致资源没有释放)而是让线程执行完。

    线程的同步原因:当多个线程对一个资源进行访问时,需要对线程进行同步,否则可能出现错误的数据。例如,火车站的售票系统就采用了线程的同步,因为火车票的数量是固定的,每个售票窗口相当于一个线程,在售票过程中,不能将一张票卖出去两次。同步需要用到的关键字:synchronized同步的两种方式:同步块和同步方法每一个对象都有一个监视器,或者叫做锁。同步方法利用的是this所代表的对象的锁。

    线程的死锁线程1锁住了对象A的监视器,等待对象B的监视器,线程2锁住了对象B的监视器,等待对象A的监视器,就造成了死锁。wait、notify、notifyAll每一个对象除了有一个锁之外,还有一个等待队列(wait set),当一个对象刚创建的时候,它的等待队列是空的。我们应该在当前线程锁住对象的锁后,去调用该对象的wait方法。当调用对象的notify方法时,将从该对象的等待队列中删除一个任意选择的线程,这个线程将再次成为可运行的线程。当调用对象的notifyAll方法时,将从该对象的等待队列中删除所有等待的线程,这些线程将成为可运行的线程。wait和notify主要用于producer-consumer(生产者-消费者)这种关系中。线程的终止设置一个flag变量。结合interrupt()方法。


    最新回复(0)