JAVA中实现多线程总结

我们知道,在操作系统级别上软件的运行一般都是以进程为单位,而在每个进程的运行过程中允许同时并发执行多个不同线程,这就使得一个程序能同时执行不同的操作。使用多线程的目的是为了最大限度地利用计算机CPU资源。JAVA程序字节码最终是在JVM虚拟机下运行的,同一虚拟机进程中的不同操作都是通过多线程来运行的。在JAVA虚拟机中,线程常用有单线程和多线程,单线程指程序执行过程只是一个有效操作的序列,不同操作都有着明确的先后顺序;而多线程允许同时进行着不同的操作,这些不同的操作同时并发进行着,并由CPU时钟频率根据不同的调度方式对他们进行执行调度。

在JAVA语言中提供了丰富的多线程操纵接口,提供了各类不同的线程实现方法供我们选择,功能非常强大。在手机软件设计中,由于同样需要执行网络连接(基于HTTP的高级Internet协议通讯)、UI调度等待、UI显示幻化、游戏控制等操作需要通过后台的数据运算或UI不断更新等操作。因此在J2ME中,KVM虚拟机也提供了功能强大的多线程API,使我们同样能在J2ME中实现线程的并发运算。

在J2ME中,主要有以下三种方法实现多线程。

一、继承Thread类(java.lang.Thread)

通过编写线程类继承Thread类并重写Thread类中的run()方法实现线程,当线程对象被运行时候将会自动执行run方法中的实体内容,从而开辟一个单独的线程并运行起来。

如:public class ThreadSimple extends Thread{

public ThreadSimple()

{

//constructor

}

public void run()

{

//run code entity

}

}

线程实例使用,直接创建对象并调用start()方法即可运行线程。

new ThreadSimple().start();

当执行start方法时候,将会自动运行run方法,但是执行start方法时候只做了一件事,就是将线程转化为可执行状态,然后等待操作系统进行调度并运行,因此无法保证线程能立即启动。在JAVA中,Thread类实现了Runnable接口,因此run方法是通过实现接口Runnable中的抽象方法。

二、直接实现Runnable多线程接口(java.lang.Runnable)

线程接口Runnable中只有一个抽象方法run,通过实现Runnable接口中的方法的类即可创建出有多线程特征的对象,但该对象并无法使其启动线程,需要作为参数并借助Thread的构造方法构造创建对象并调用start方法对线程进行启动。

如:public class RunnablSimple implements Runnable{

public RunnableSimple()

{

//constructor

}

public void run(){

//run code entity

}

}

实现类型的对象使用:

RunnableSimple rs = new RunnableSimple();

new Thread(rs).start();

由此可见,以上两种方法都是通过Thread的start来启动线程的,实际上所有的线程操作都是封装在Thread这个类中,由Thread对象调用各种接口来控制线程。

J2ME中线程中主要方法:

void setPriority(int newPriority),设置线程优先级,在操作系统中线程的调度是不确定性的,可以通过该方

法设置相应线程的优先级别。

static void sleep(long millis) ,线程中静态方法,用于让线程进入休眠状态,执行该方法将会让线程在指定时间millis毫秒内休眠。

void start(),使现在进入可执行状态。

void run() ,线程执行主体。

void join(),等待该线程终止。

boolean isAlive(),用于判断线程是否出于Alive状态。

static void yield() ,尽量让其他线程先执行。

三、使用任务组合实现多线程

在J2ME中,同样具有JAVA中的任务处理组合类,他们分别为Timer和TimerTask,可以使用他们实现多线程,简单说就是定时实现任务。

Timer是JAVA中的一个定时器,可以实现在某一时间做某件事或者在某一时间段做某些事,分别通过方法schedule(TimerTask tt,long millis)和schedule(TimerTask tt,long start,long off)。

TimerTask是一个任务类,通过继承该类并覆盖方法run即可创建一个任务。

如:public class TimerTaskS extends TimerTask{

public TimerTaskS(){

//constructor

}

public void run(){

//run code entity

}

}

任务调用:

Timer timer = new Timer();

//3秒钟后执行任务

timer.schedule(new TimerTaskS(),3000);

//3秒钟后执行任务并且之后每5秒钟执行一次

timer.schedule(new TimerTaskS(),3000,5000);

有此可见在使用计时任务可以达到实现线程的效果,分别执行不同的并发操作,通过Timer类对象来操作TimerTask对象,通过schedule方法来计时执行任务,在结束任务的时候,通常使用cancel()来实现。

通常情况下,在J2ME软件中我们通过手机按键来触发一系列相应的操作,在程序响应处理过程中较多会涉及网络操作、数据存储等相对消耗时间和资源的操作,而这些操作往往需要一定的时间才能完成,因此在处理按键响应过程中通常我们需要建立线程处理,避免程序出现死机现象。

public void commandAction(Command c, Displayable s) {

if(c==do1Com){

//创建实现接口线程

new Thread(new RunnableSimple()).start();

}

else if(c==do2Com){

//创建继承Thread线程

new ThreadSimple().start();

}

else{

//创建任务线程

new Timer().schedule(new TimerTaskS(),3000,20);

}

}

 

第二篇:Java多线程总结

多线程总结

在学习编程的过程中,我觉得不止要获得课本的知识,更多的是通过学习技术知识提高解决问题的能力,这样我们才能走在最前方,更多Java学习,请登陆疯狂java官网。

1.重写线程Thread,Runnable运行的是run方法,当调用线程start()时,会运行其run方法,

也可以主动去调用,只不过不在同一个线程里。

当一个线程既继承了Thread又继承Runnable,其thread必须调用target.run()实现对runnable的方法调用。

2.Object:的三种线程方法 wait() ,notify() ,notifyAll()

在某个线程里执行某个对象锁的wait方法会暂停该线程的运行,在另外一条线程里利用该锁的notify方法

可以唤醒某个该对象锁所在的线程;当该对象锁在多个线程里wait的时候,可以使用notifyAll唤醒运行。

3.线程调度-休眠/优先级/让步/合并/守护线程

休眠。静态方法Thread.sleep();谁调用谁休眠

对于优先级高的线程获取CPU机率比较大,并不一定优先级低的运行不了线程的让步含义就是使当前运行着线程让出CPU资源,但是然给谁不知道,仅仅是让出,线程状态回到可运行状态。Thread.yield()

线程的合并的含义就是将几个并行线程的线程合并为一个单线程执行,应用场景是当一个线程必须等待另一个线程执行完毕才能执行时可以使用join方法。 调用某个线程的join(),该线程运行完才运行调用它的线程代码。

守护线程的特征是当setDaemon(boolean on)将该线程标记为守护线程或用户线程。

当正在运行的线程都是守护线程时,Java 虚拟机退出。

该方法必须在启动线程前调用。实际上:JRE判断程序是否执行结束的标准是所有的前台执线程行完毕了,而不管后台线程的状态

4.线程的同步-同步方法/同步块

在多个线程运行的时候,是否有竞争资源同时改动。应该把竞争资源设为私有,并提供修改方法。可以是对修改方法的同步,也可以对代码块同步。 同步使用synchronized关键字。

5.线程池-JAVA5 API

固定线程池:

//创建一个可重用固定线程数的线程池 ExecutorService pool =

Executors.newFixedThreadPool(2);

//创建一个使用单个 worker 线程的 Executor,以无界队列方式来运行该线程。

ExecutorService pool = Executors.newSingleThreadExecutor();

//当要加入的池的线程(或者任务)超过池最大尺寸时候,则入此线程池需要排队等待。一旦池中有线程完毕,则排队等待的某个线程会入池执行。 可变尺寸的线程池:

//创建一个可根据需要创建新线程的线程池,但是在以前构造的线程可用时

将重用它们。 ExecutorService pool = Executors.newCachedThreadPool(); 延迟连接池:

//创建一个线程池,它可安排在给定延迟后运行命令或者定期地执行。 ScheduledExecutorService pool = Executors.newScheduledThreadPool(2); //pool.execute(t3); //使用延迟执行风格的方法 pool.schedule(t4, 10, TimeUnit.MILLISECONDS);

//单任务延迟线程池:

//ScheduledExecutorService pool =

Executors.newSingleThreadScheduledExecutor();

6.有返回值的线程-JAVA5 API

线程不再继承runnable借口,而是callable接口并重写call方法。通过线程池submit调用,返回的Future对象,通过get()方法取得返回的对象。

7.线程锁:-JAVA5 API

Lock类代替synchronized,在需要同步的代码块里调用lock(),unlock(). -ReentrantLock

ReadWriteLock 用于I/0读写。

-ReentrantReadWriteLock

8.-JAVA5 API

//阻塞队列:java.util.concurrent.BlockingQueue继承了Queue接口,且是固定个数的队列,当队列满了,需要继续添加,或者队列没有元素,需要取出时,队列阻塞。

//阻塞栈:对于阻塞栈,与阻塞队列相似。不同点在于栈是“后入先出”的结构。

java.util.concurrent.BlockingDeque

是JAVA6 API中新提出的一个类。

9.线程调度-JAVA5 API

通过Lock对象的newCondition()得到Condition对象,并调用其await();signalAll();等。对应了Object中wait();

notifyAll();

10.原子量-JAVA5 API

java.util.concurrent.atomic的使用需要Lock的配合。

11.障碍器-JAVA5 API

CyclicBarrier c=CyclicBarrier(等待子线程数, 等待完毕需要执行的Runnable);子线程需要调用c的await().来通知主线程已经完成了子任务。

疯狂Java培训专注软件开发培训,提升学员就业能力,重点提升实践动手能力。技术知识沉淀深厚的老师,让你感受Java的魅力,激发你对于编程的热爱,让你在半年的时间内掌握8-10万的代码量,掌握Java核心技术,成为真正的技术高手;通过大量全真企业项目疯狂训练,迅速积累项目经验。让你成为技能型的现代化高端人才,迅速获得高薪就业!时间不等人,赶紧联系我们吧!

相关推荐