Java 线程简介

来源:互联网 发布:导入java.util.base64 编辑:程序博客网 时间:2024/06/06 11:49

1. 线程的创建

1.1 扩展java.lang.Thread类

1)通过继承java.lang.Thread类,并重写run方法,该run方法代表了线程将要执行的任务,所以说run方法也称为执行体;
2)创建Thread类子类的实例,即创建了线程对象,然后调用对象的start()方法;
程序示例如下:

public class Main4 extends Thread {    @Override    public void run(){        System.out.println("Thread: "+getName());  //获取线程的名字    }    public static void main(String args[]){        Main4 t=new Main4();        System.out.println("thread: "+Thread.currentThread().getName());        t.start();    }}

1.2 实现Runnable接口

1)定义一个类,该类实现了Runnable接口中的run方法,run方法体即为线程执行体;
2)创建Runnable实现类的对象,并将其作为Thread类的构造参数创建Thread类对象,即线程对象;
3)调用该线程对象的start()方法开始启动线程;

下面来了解一下Thread类的构造方法:

//无参数构造函数,并将“Thread-n(n为内部nextThreadNum()函数自动生成的数字)”作为线程的名字;public Thread();//将实现了Runnable接口的对象作为参数,线程对象执行的是target所指向对象中的run方法;//将“Thread-n(n为内部nextThreadNum()函数自动生成的数字)”作为线程的名字;public Thread(Runnable target);//ThreadGroup类型参数用于设置新创建线程所属的线程组,Runnable接口类型参数用于设置线程执行的run方法体、//将“Thread-n(n为内部nextThreadNum()函数自动生成的数字)”作为线程的名字;public Thread(ThreadGroup group, Runnable target);//String类型参数用于设置线程的名字public Thread(String name)public Thread(ThreadGroup group, String name);public Thread(Runnable target, String name);public Thread(ThreadGroup group, Runnable target, String name);//stackSize参数用于设置线程所需的栈的大小,如果等于0,表示忽略该参数public Thread(ThreadGroup group, Runnable target, String name,long stackSize);

示例程序如下:

public class Main5 implements Runnable {    public void run(){        System.out.println(Thread.currentThread().getName());    }    public static void main(String args[]){        Main5 task=new Main5();        Thread t=new Thread(task,"hello");        t.start();    }}

1.3 通过Callable和FutureTask创建

1)创建Callable接口的实现类,并实现call方法,call方法体为线程体,并有返回值;
2)创建FutureTask对象,通过FutureTask对象封装Callable对象,FutureTask对象同时封装了call方法返回值;
3)将FutureTask对象作为target参数构造Thread对象并启动对象;
4)通过FutureTask对象的get方法获取call方法的返回值;

实例程序如下:

import java.util.concurrent.Callable;import java.util.concurrent.FutureTask;public class Main6 implements Callable<Integer> {    public Integer call(){        System.out.println(Thread.currentThread().getName());        return 0;    }    public static void main(String args[]){        Main6 callable=new Main6();        FutureTask<Integer> futureTask=new FutureTask<Integer>(callable);        Thread t=new Thread(futureTask,"hello");        t.start();    }}

1.4 各种创建线程方法的对比

采用实现Runnable、Callable接口来创建线程的优势:
Thread对象只是实现了Runnable或者Callable接口,还可以继承其他的类。同时在这样方式下,多个线程共享一个target对象,非常适合用于多个线程处理一份数据的情况。在这种方式下,将CPU、执行代码、数据分离开来,符合面向对象编程的思想。

采用实现Runable、Callable接口来创建线程的劣势:
当需要访问当前线程时,只能通过Thread.currentThread()方法进行访问。

采用继承Thread类创建线程的优势:
代码简单,如果需要访问当前线程,只需要简单通过this指针即可。

采用继承Thread类创建线程的劣势:
该类已经继承了Thread类,不能在继承其他的类。

2. 线程的状态

Thread线程对象在运行过程中,可能存在不同的状态,在java.lang.Thread.State中详细进行了介绍:
NEW状态:线程刚被创建,还未调用start方法;

RUNNABLE状态:可运行状态,等待JVM虚拟机的调度;

BLOCKED状态:阻塞状态,在等待锁进入synchronized修饰的方法或者代码区;或者等待IO操作;

WAITING状态:等待状态,一个线程处于WAITING状态是因为调用了以下其中一个方法:
不带时间参数的Object.wait()、不带时间参数的Thread.join()、LockSupport.park();
一个线程处于WAITING状态通常是在等待另外一个执行某些特定的动作。
例如说,当某个线程调用某个对象的object.wait()方法而处于WAITING状态时,那么就会等在其他的线程调用该对象的object.notify()或者object.notifyAll()方法;
当一个线程调用Thread.join()方法而处于WAITING状态时,是在等待另外一个线程的终止;

TIMED_WAITING状态:带指定等待时间的等待状态,线程处于该状态是因为调用了如下带特定时间参数的方法:
带特定时间参数的Thread.sleep()、带特定时间参数的Object.wait()、带特定时间参数的Object.join()、LockSupport.parkNanos()、LockSupport.parkUntil();

TERMINATED状态:终止状态,线程完成了执行

3. 线程间通信

1)共享变量
2 )wait, notify机制
3)Lock, Condition机制
4)管道

参考博客:
http://blog.csdn.net/longshengguoji/article/details/41126119

原创粉丝点击