Java多线程(一)

原创 2016年08月30日 17:14:14

Java线程被称为是轻量级的进程,一个进程可以有多个线程,一个线程必须要有一个父进程。线程是独立运行的。

Java使用Thread类代表线程,所有线程对象都必须是Thread类或者子类的实例。

同一个进程可以由多个线程并发进行。多线程之间内存共享容易,实现多任务并发效率高,多线程是非常有用的。


创建多线程

创建线程有三种方式:继承Thread类,实现Runnable接口,使用Callable和Future创建

一、继承Thread类创建

1.定义子类,重写run()方法,run()方法是线程执行体

2.创建子类实例,即创建了线程对象

3.调用线程对象start()方法启动线程

public class ChildThread extends Thread{
    public void run(){
        //这里写要执行的语句执行体
    }
    public static void main(String[] args){
        Thread thread_1 = new ChildThread();
        thread_1.start();
    }
}

使用继承Thread类的方法创建线程类时,多线程间不能共享线程类实例变量。


二、实现Runnable接口创建

1.定义Runnable接口的实现类,重写run()方法,依然是线程的执行体

2.创建实例,以此实例为Thread的target创建Thread对象,该Thread对象是真正的线程对象

public class RunThread implements Runnable{
    public void run(){
        //这里写要执行的语句执行体
    }
    public static void main(String[] args){
        RunThread runThread = new RunThread();<span style="white-space:pre">	</span>//创建Runnable对象
        Thread trueThread = new Thread(runThread);<span style="white-space:pre">	</span>//用Runnable对象创建线程对象
        trueThread.start();
    }
}
和继承Thread相比,实现Runnable接口的方法不能直接创建线程对象,必须先创建Runnable对象在进一步创建线程对象。

Runnable接口是函数式接口(只有一个抽象方法的接口,可以包含多个默认方法和类方法),可用Lambda表达式创建Runnable对象。


三、使用Callable和Future创建线程

Callable提供了一个call()方法作为线程执行体,call()有返回值,并且可以声明抛出异常

Future接口代表call()方法的返回值,有一个FutureTask实现类,实现了Future和Runnable接口,可以作为Thread类的target

Callable接口同样是函数式接口,可用Lambda表达式创建Callable对象。

线程启动步骤:

1.创建Callable接口实现类,实现call()方法,call()方法作为线程执行体,有返回值,再创建实现类实例

2.使用FutureTask包装Callable对象,该Futuretask对象封装了返回值

3.使用FutureTask对象创建启动线程

4.调用FutureTask对象的get()方法获得子线程结束的返回值

public class FirstCall implements Callable{
    public void call throws Exception(){
        //这里写要执行的语句执行体
        return ;	//可以有返回值
    }
    public static void main(String[] args){
        Callable callable = new FirstCall();	//创建Callable对象
        FutureTask firstTask = new FutureTask(callable);	//创建FutureTask对象
        Thread trueThread = new Thread(firstTask);	//用FutureTask对象创建线程对象
        trueThread.start();
    }
}
也可以使用Lambda表达式直接创建Callable对象,这样就无需创建Callable实现类和Callable对象了。

public class CallThread{
    public static void main(String[] args){
    	CallThread callhread = new CallThread();	//创建Callable方法

	    FutureTask<Integer> task = new FutureTask<Integer>((Callable<Integer>)()->{
	    	//这里直接写call方法里面执行体,不用写call()
	    });

        new Thread(task).start();
   }
}

三种实现多线程的方式都可以实现,实现Runnable接口和实现Callable接口方式基本相同,可以归为一种方式。这种方式和继承Thread差别在于:

采用Runnable或Callable接口的方式优缺点:

1.线程类只实现了Runnable或Callable接口,可以继承其他类

2.多个线程可以共享一个target,适合多个相同线程处理同一份资源。

3.缺点:编程复杂,想访问当前线程,必须用Thread.currentThread()方法

采用继承Thread创建方式的优缺点:

1.编写简单,直接用this即可获得当前线程

2.缺点:已经继承了Thread类,不能继承其他父类


因此通常采用实现Runnable接口或Callable接口创建多线程


线程生命周期

线程生命周期包括新建(New)、就绪(Runnable)、运行(Running)、阻塞(Blocked)、死亡(Dead) 5种

New新建一个线程,当线程对象调用start()线程处于就绪状态,表示可以运行了,只能对处于新建状态的线程调用start()方法,否则会引发异常。

线程一下情况会进入阻塞状态:

1.调用sleep()主动放弃

2.调用了阻塞IO的方法,该方法返回之前,线程被阻塞

3.试图获得一个同步监视器,但该同步监视器正被其他线程持有

4.等待某个通知(notify)

5.调用了suspend()方法将线程挂起

针对这些情况,发生如下情况可解除阻塞:

1.调用sleep()方法的线程经过了指定时间

2.调用的阻塞IO方法已经返回

3.成功获得同步监视器

4.在等待某个通知时,其他线程发出通知

5.调用resume()恢复

测试线程是否死亡可调用线程对象的isAlive()方法,不要对已经死亡的线程调用start()方法,否则会引发异常


版权声明:本文为博主原创文章,未经博主允许不得转载。

多线程Callable和Future

---------------------- android培训、java培训、期待与您交流! ----------------------   关于多线程Callable和Future    ...
  • zhuangxingrui86
  • zhuangxingrui86
  • 2012年08月14日 16:43
  • 6505

多线程

线程和进程 1.进程是处于运行过程中的程序,其具有一定的独立功能,有以下3个特点: 独立性:进程是系统中独立存在的实体,它可以拥有自己独立的资源,每一个进程都拥有自己私有的地址空间,在没有经过进...
  • xuguoli_beyondboy
  • xuguoli_beyondboy
  • 2015年03月17日 10:06
  • 557

Java 多线程(二)——创建线程(Thread、Runnable、Callable)

采用实现Runnable、Callable接口的方式创建多线程; 采用继承Thread类的方式创建多线程;...
  • Zen99T
  • Zen99T
  • 2016年03月04日 17:01
  • 1366

JAVA基础学习--一个线程加一运算,一个线程做减一运算,多个线程同时交替运行--synchronized

使用synchronized package com.pb.thread.demo5; /**使用synchronized * 一个线程加一运算,一个线程做减法运算,多个线程...
  • ko0491
  • ko0491
  • 2015年09月19日 19:41
  • 1120

java多线程查询

由于最近工作遇到性能问题,尝试研究用多线程来实现,结果速度快了好几倍 下面是多线程查询的部分代码,提供给大家参考下: 线程类: 带返回值的类要实现Callable接口,具体业务逻辑没有实现,只是写了个...
  • zhaishanhui
  • zhaishanhui
  • 2015年05月22日 12:37
  • 605

Java 之 线程的创建和启动(三)

之前给大家介绍了通过实现Runnable接口创建和启动线程类。通过实现Runnable接口创建多线程时,Thread类的作用就是把run方法包装成线程执行体。从Java 5 开始,Java提供了Cal...
  • u010786678
  • u010786678
  • 2016年05月29日 21:26
  • 756

多线程创建方式总结

今天给别人说创建线程方式,一个是new Thread(一个实现runnable的对象),一个是实现callbale的对象,意思就是像给他说future。实际没说到位,还有一个是extend Threa...
  • zengxiaosen
  • zengxiaosen
  • 2018年02月07日 22:00
  • 17

java多线程的共享变量访问控制实例

最近打算去一家电商公司,对于高并发的数据访问控制有着严格的要求,近期打算把多线程的知识在好好补一下。 线程调度有五个状态; 开始,可运行,运行,阻塞,死亡。 启动线程有两种方法。继承Thread...
  • micro_hz
  • micro_hz
  • 2015年09月11日 15:44
  • 3552

Java核心技术卷1 第十四章 多线程

14.1 什么是线程 一个程序同时可以执行多个任务。通常,每一个任务称为一个线程,可以同时运行一个以上线程的程序称为多线程程序。多进程与多线程的区别: 每个进程拥有自己的一整套变量,而线程则...
  • qq_30154277
  • qq_30154277
  • 2016年07月02日 21:55
  • 427

创建线程的三种方式优缺点

Java使用Thread类代表线程,所有的线程对象都必须是Thread类或其子类的实例。 一、继承Thread类创建线程类 1.重写run方法。该run()方法的方法体就代表了线程需要完成的任务 ...
  • sinat_27933301
  • sinat_27933301
  • 2017年04月10日 11:08
  • 941
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Java多线程(一)
举报原因:
原因补充:

(最多只允许输入30个字)