多线程的学习

线程与进程

进程是程序的一次动态执行过程,包括代码加载、执行到执行完毕的一个完整过程。

线程是比进程更小的执行单元,是在进程的基础上进一步划分的。多线程是实现并发机制的一种有效手段,所谓多线程指的是一个进程在执行过程中产生多个线程,这些线程可以同时存在、运行。线程一定要依附进程才能够存在。

多线程实现

多线程的实现包括:继承Thread类实现Runnable(Callable)接口

继承Thread类

java.lang.Thread是一个负责线程操作的类,任何类继承Thread类就成为一个线程的主类,线程启动的主方法需要覆写Thread类中的run()方法实现

线程的执行和进程一样,需要轮流去抢占资源,所以多线程的执行也是多个线程彼此交替执行。多线程的启动唯一方法是Thread类中的start()方法:public void start()

为什么多线程的启动是start()不是run()?

Thread类中的start()方法不仅要启动多线程的执行代码,还要根据不同的操作系统进行资源分配

实现Runnable接口

继承Thread类最大的缺点是单继承问题,Java可以通过Runnable接口实现多线程,线程的主类只需要覆写此方法就可以。多线程的启动是通过Thread类的一个有参构造:public Thread(Runnable target),可以接受一个Runnable接口对象--->new Thread(对象).start()

两种多线程实现方法的区别

从Java实际开发角度来看。肯定是Runnable接口,可以有效避免单继承的局限。

Thread类的定义

public class Thread extends Object implements Runnable

通过Thread类的定义,可以发现Thread类也是Runnable接口的子类。

Runnable接口和Thread类还有一个特点:使用Runnable接口可以更加方便表现出数据共享的概念。

多线程两种实现方式和区别,分别编写程序验证两种实现方式?

● 多线程两种实现方式都需要一个线程的主类,可以实现Runnable类或者继承Thread类,都需要在子类中覆写run()方法,此方法为线程的主方法

● Thread类是Runnable接口的子类,而且使用Runnable接口可以避免单继承局限,并且更加方便实现数据共享的概念。

程序实现结构如下:

Runnable接口

Thread类

class MyThread implements Runnable{

@Override

public void run(){ //线程主方法

//线程操作方法

}

}

class MyThread extends Thread{

@Override

public void run(){ //线程主方法

//线程操作方法

}

}

MyThread mt=new MyThread();

new Thread(mt).start();

MyThread mt=new MyThread();

mt.start();

利用Callable接口实现多线程

Runnable接口虽然可以避免单继承性,但是Runnable接口run()方法不能返回操作结果。Java对于多线程实现提供了一个新的接口:java.util.concurrent.Callable;接口中存在一个call()方法,可以实现线程操作数据的返回,返回的数据类型由Callable接口上的泛型类型动态决定。

Callable类的定义

@FunctionalInterface(函数式接口)

public interface Callable<V>{

public V call() throws Exception;

}

Thread类中没有定义任何构造方法可以直接接受Callable接口对象实例,由于需要接受call()方法返回值的问题,Java提供了一个新的类:java.util.concurrent.FutureTask<V>,实现了RUnnableFuture接口,而RunnableFuture接口同时实现了Future与Runnable接口

public class FutureTask<V>extends object implements RunnableFuture<V>

线程的操作状态

任何线程一般包括五种状态:

  • 创建:程序中用任何方法创建一个线程对象后,新的线程对象便处于新建状态

  • 就绪:调用线程的start()方法就可以启动线程,当线程启动,线程就进入就绪状态
  • 运行:当就绪状态的线程被调用并获得处理器资源时,线程就进入运行状态了
  • 堵塞:一个正在执行的线程被认为挂起或需要执行耗时的输入输出操作时,将让出CPu并暂时中止自己的执行,进入阻塞状态。调用sleep()、suspend()、wait()等方法,线程将进入堵塞状态
  • 终止:调用stop()或run(0方法结束后,就处于终止状态

多线程常用操作方法

线程的命名与取得

每一次线程程序的执行都会是不同的结果,会根据自己的情况进行资源的抢占,要想区分每一个进程,就必须依靠线程的名字。对于线程的名字一般而言会在启动之前进行定义。

public static Thread currentThread()

取得当前线程对象的方法

public Thread(Runnable target,String name)

实例化线程对象,接受Runnable接口子例化对象,同时设置线程名称

public final void setName(String name)

设置线程名字

public final void getName()

取得线程名字

 

多有的线程都是在进程的基础上划分的,进程在哪里

每一个JVM运行就是进程。

用户使用Java指令执行一个类时就表示启动了一个JVM的进程,而主办方只是这个进程上的一个进程而已,当一个类执行完毕后,此进程就会自动消失

每一个JVM进程都至少启动一下两个进程

● main线程:程序的主要执行,以及启动线程

● gc线程:负责垃圾收集

线程的休眠

线程的休眠让程序执行速度变慢一点:public static void sleep(long millis) throws InterruptedException。休眠单位是毫秒(ms).

线程的优先级

  • 最高优先级:MAX_PRIORITY

  • 中等优先级:NORM_PRUORITY

  • 最低优先级:MIN_PRIORITY

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值