你的位置:首页 > Java教程

[Java教程]java 多线程笔记

一、先简单粗暴解释一下一些与线程有关的概念  1.并行与并发   并行:多个cpu实例或者多台机器同时执行一段处理逻辑,是真正的同时。   并发:通过cpu调度算法,让用户看上去同时执行,实际上从cpu操作层面不是真正的同时。  2.资源共享   多个线程调用资源,是同一个或多个资源。  3.线程安全   在并发的情况之下,代码经过多线程使用,线程的调度顺序不影响最后结果,则是线程安全的。  3.同步    Java中的同步指的是通过人为的控制和调度,保证共享资源的多线程访问成为线程安全。例如使用@synchronized。

  Java线程具有五中基本状态

  新建状态(New):当线程对象对创建后,即进入了新建状态,如:Thread t = new MyThread();

  就绪状态(Runnable):当调用线程对象的start()方法(t.start();),线程即进入就绪状态。处于就绪状态的线程,只是说明此线程已经做好了准备,随时等待    CPU调度执行,并不是说执行了t.start()此线程立即就会执行;

  运行状态(Running):当CPU开始调度处于就绪状态的线程时,此时线程才得以真正执行,即进入到运行状态。注:就     绪状态是进入到运行状态的唯一入    口,也就是说,线程要想进入运行状态执行,首先必须处于就绪状态中;

  阻塞状态(Blocked):处于运行状态中的线程由于某种原因,暂时放弃对CPU的使用权,停止执行,此时进入阻塞状态,直到其进入到就绪状态,才 有机会再次   被CPU调用以进入到运行状态。根据阻塞产生的原因不同,阻塞状态又可以分为三种:

   1.等待阻塞:运行状态中的线程执行wait()方法,使本线程进入到等待阻塞状态;

   2.同步阻塞 -- 线程在获取synchronized同步锁失败(因为锁被其它线程所占用),它会进入同步阻塞状态;

   3.其他阻塞 -- 通过调用线程的sleep()或join()或发出了I/O请求时,线程会进入到阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕    时,线程重新转入就绪状态。

  死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期   二、实现Runnable接口相比继承Thread类有以下好处:1.避免单继承的局限,一个类可以实现多个接口2.适合资源的共享。
通过例子说明资源共享:  Runnable接口:    测试:    结果:明显Runnable可以实现资源共享  

Thread父类:

  

  测试:

  

  结果:没有实现资源共享

  

 

总结: 

(资源共享)  java多线程访问共享资源的方式:    (1).如果每个线程执行的代码相同,可以使用同一个Runnable对象,这个Runnable对象中有那个共享数据。    (2).如果每个线程执行的代码不同,这时候需要使用不用的Runnable对象,这种情况有两种方式实现:    1.将共享资源封装在另一个对象中,然后将这个对象逐一传给各个Runnable对象(在java中,对象(同过new来生成的对象)作为参        数传递时,传递的是对象的地址),每个线程对共享数据的操作方法也分配到那个对象身上去完成,这样容易实现针对该数据        进行各个操作的互斥和通信。    2.将这些Runnable对象作为某一个类中的内部类,共享数据作为这个外部类中的成员变量,每个线程对共享数据的操作也分配给外        部类,以便实现对共享数据进行各个操作的互斥和通信,作为内部类的各个Runnable对象调用外部类的这些方法。      总之,要同步互斥的几段代码最好放在几个独立的方法中,这些方法再放在一个类中,这样比较容易实现他们之间的互斥和通        信。(3).简单极端的方式,在任意一个类中定义一个static变量,static变量将被所有线程共享 (同步)。同步方法/同步代码块    注:同步是一种高开销的操作,因此应该尽量减少同步的内容。       通常没有必要同步整个方法,使用synchronized代码块同步关键代码即可。