Java学习总结之线程

说到线程,学过操作系统的人应该会比较容易理解,并行的程序叫进程,而程序内部并行的部分就叫线程,或者说线程是程序内部同时进行的不同执行路径。线程并不能独享资源,而是多个线程共享同一个进程内部的资源,这样的话,多个线程同时访问同一个数据的时候,很容易出现脏数据,也就是A写B写A读这种顺序的情况下读到的数据,本来A读应该读取自身A写入的数据,但是在A写入之后,线程B又进行了写操作,那么A读到的实际是B写入的数据,这就是脏数据。

所以线程需要考虑线程安全的问题。

线程有什么优点呢?①是提高界面的速度,比如说界面中需要输入数据,而接收用户输入是一种阻塞式的方法,那么需要数据的时候,界面就只能一直等待着用户输入完毕才能继续执行,无论后面的内容是否全部都与该数据相关;如果是多线程,则可以用一个新线程专门处理用户输入,主线程则处理界面的其他事件,这样会让用户感觉界面速度提高了,②是充分利用资源,多个线程可以同时执行,即使一个线程被阻塞了,也不会影响另一个线程的运行,可以更有效的利用菜谱资源。

下面说明线程的使用方法。常用的有两种,一种是继承线程类,另一种是实现Runnable 接口。此外还有Timer+TimerTask 模式。

 ①继承Thread 类:声明类时加入extends Thread 语句。继承Thread 类后,将自定义的线程代码写在线程体 run 方法内部,则线程开始之后会自动执行run 方法内部的代码,run 方法执行完后线程死亡。

main 方法由系统线程运行,main 方法执行完毕后并不立即死亡,而是要等到其所有子线程死亡后才死亡,为了让子线程在main 方法结束后就结束,可以将子线程设置为后台线程。用 对象名.setDaemon(true)进行设置。通过 对象名.start ()来启动线程,进入run 方法。

注:一个类可以创建多个线程对象,但每个对象只能启动一次。另外多个线程之间的执行顺序并不固定。

②实现 Runnable 接口:声明类时加入implements  Runnable 语句。同样将自定义线程代码写在 run 方法内部。调用时略微麻烦,需要创建新线程。

new Thread(new  实现了Runnable 接口的类()).start ( ) ;

建议使用这种方法,因为这种方法更加灵活,没有对父类的限制要求,有利于程序将来的扩展。而且一个对象可以用来创建多个线程。

多线程问题:由多线程的并发,引起了一些资源访问的问题,也就是前文提到的脏数据问题。主要的解决办法是使用关键字 synchronized  。

一个对象,对于类内部由synchronized 关键字限定的成员或代码块,同一时间仅限一个线程访问。这句话中有多个限定词,“一个对象”,被限定的代码,同一时间。这里分别进行说明,被锁住的是“一个对象”,而不是所有由该类产生的对象,这是因为每个对象都有自己对应的资源区域,操作的都是自己的资源。而脏数据的产生是因为多个线程对同一资源的读写才产生的。被限定的代码,也就是说对非 synchronized 关键字限定区域的代码来说,仍然可以由多个线程在同一时间进行访问,同时,被限定的代码也可以有多块,只要有一块正在被某个线程访问,则剩余的也被锁定,无法被其他线程访问。同一时间,当某个线程从被限定区执行完毕时,另一个线程才可以进入,被限定区只会接受一个或零个线程的访问。

synchronized 可以限定代码块,可以修饰方法,也可以限定某个成员属性。在synchronized 修饰的区域可以使用wait 和 notify 方法,wait 表示当前线程放弃对当前对象资源的锁定,进入等待状态,其他线程可以开始争夺当前对象的“锁”了;notify 表示唤醒进入wait 状态的线程,使其重新加入争夺当前对象的锁的队伍。

优先级:使用setPriority 方法可以设置线程的优先级,默认是NORM_PRIORITY (= 5),最高是MAX_PRIORITY (= 10),最低是 MIN_PRIORITY( = 1)。

另外,说明几个比较重要的方法。静态方法sleep:使线程沉睡一定毫秒,与wait 所不同的是此时线程不放开对当前对象的锁。join:在A线程中加入B.join();代表着A线程执行到这条语句时等待B线程先执行,B执行完毕A才继续执行。

线程池Executors:比起线程,在经常性的创建、释放的情况下,线程池效率要高出不少。因为线程池省去了线程的创建和释放过程,在需要线程的时候向线程池申请即可,线程池即会将造就创建好的线程分配给申请者使用。使用完后放回线程池,等待分配给下一个申请者。

有返回值的线程Callable:使用方法如下:

public  class  类名  implements  Callable<返回值类型> {

    public  返回值类型  call()  throws  Exception {

             //线程代码,类似run方法

     }

}

 

你可能感兴趣的:(Java学习总结,java,线程)