Java之线程基础

简介

  本文主要介绍Java编程中线程的基础知识,包括线程介绍、线程的五大状态、线程的三种创建方式、线程的同步,最后根据线程的经典问题——生产者消费者模型,给出了实现的源代码。
  通过本文的学习,可以掌握基本的Java多线程编程。

一、线程介绍

   若将操作系统中的任务看成进程,那么任务中的多个执行流可以看做是多个线程。
  进程是系统进行资源分配和调度的一个独立单元。
  线程是进程的组成部分,一个进程可以拥有多个线程,一个线程必须有一个父进程。线程可以拥有自己的堆栈、自己的程序计数器和自己的局部变量,但不拥有系统资源,它与父进程的其他线程共享该进程所拥有的全部资源。

二、线程的五大状态

  每个线程都有自己的生命周期,通常将生命周期分为5个状态(阶段),即新建(New)、就绪(Ready)、运行(Running)、阻塞(Blocked)、死亡(Dead)。

1、新建状态

  当使用new关键字新创建一个Thread对象时,该线程就进入了新建状态。JVM会为新建的线程分配内存、并初始化线程对象的成员变量,线程对象的执行体还未启动。

2、就绪状态

  当一个线程对象执行了start()成员方法时,该线程便进入了就绪状态。JVM开始为线程对象创建方法调用栈和程序计数器。此时线程对象同样没有运行,只代表线程对象可以运行,运行时机取决于JVM的线程调度器。

3、运行状态

   当JVM调度器调度就绪状态的线程对象时,即执行线程对象的run()方法,那么该线程对象进入了运行状态。
  对於单个处理器中存在多个线程时,处理器采用时间片轮换的方式来执行各个线程。

4、阻塞状态

  为了使多个线程都可到执行,那么处于运行状态的线程对象不可能一直处于运行状态。当被中断时,线程对象从运行状态变为了阻塞状态。
  线程进入阻塞状态的情况:

  •   遇到 sleep();
  •   遇到 join();
  •   遇到 wait();
  •   遇到 read()、write();

5、死亡状态

  当线程生命周期结束时,线程对象便进入了死亡状态,进入死亡状态的线程不能重进入其它任何状态,只能静静等着JVM垃圾回收机制来回收自己。

三、线程的三种创建方式

  JDK中提供了三种创建线程对象的方式,如继承Thread、实现Runnable、实现Callable。

1、继承Thread

  线程对象类直接继承Thread类,并重写Thread类的run()方法。如下所示:

public class ThreadTest extends Thread{
	@Override
	public void run() {
		// 执行体代码
	}	
}

  该线程对象的运行,如下所示:

public static void main(String[] args) {
	Thread thread01 = new ThreadTest();
	thread01.start();	
}

2、实现Runnable

  Runnable是一个接口,线程对象类可以实现该接口,并重写Runnable接口的run()方法。如下所示:

public class ThreadTest implements Runnable{
	@Override
	public void run() {
		// 执行体代码
	}	
}

  该线程对象的运行,如下所示:

public static void main(String[] args) {
	ThreadTest thread01 = new ThreadTest();
	new Thread(thread01, "Thread-name").start();	
}

3、实现Callable

  实现Callable接口的线程,创建过程如下:

  •   1.创建一个线程,创建Callable的实现类Race,并且重写call方法;
  •   2.得到Future对象;
  •   3.获取返回值;
  •   4.停止服务;
//返回Interger类型
public class ThreadTest implements Callable<Integer>{
	@Override
	public Integer call() {
		//执行体代码
		return Integer;
	}
}

  该线程对象的运行,如下所示:

public static void main(String[] args) {
	ExecutorService ser = Executors.newFixedThreadPool(2);		
	ThreadTest threadTest = new ThreadTest();			
	//获取值
	Future<Integer> result = ser.submit(threadTest);
		
	try {
		int numR = result.get();
	} catch (InterruptedException e) {
		e.printStackTrace();
	} catch (ExecutionException e) {
		e.printStackTrace();
	}
		
	//停止服务
	ser.shutdown();
}

四、线程的同步

  在多线程的情况下,会存在对公共资源进行访问的行为,也就是资源的竞争关系,其中同步就是多线程编程中处理竞争关系的一种方法,它使多线程访问公共资源时是安全有效的。同步使用synchronized关键字,其中又分为synchronized方法synchronized块

1、synchronized方法

  用synchronized关键字修饰类的一个方法,如下所示:

public synchronized void seats() {
	//需要同步的对象属性操作代码
}

  用synchronized关键字修饰的一个作用块,如下所示:

synchronized(ThreadTest.class) {
	//需要同步的对象属性操作代码
}

五、生产者消费者实例

  多线程编程中,最经典的问题就是生产者消费者问题:
  生产者负责生产产品,消费者购买产品,当库存为空的时候,生产者继续生产,消费者购买数量要小于等于库存上限,不能出现,生产一次,消费两次,或者生产了没有消费的情况。
  我的代码实现如下:

import java.util.ArrayList;
import java.util.List;

public class Cooperation {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		PipeHandle pipe = new PipeHandle();
		
		Productor productor = new Productor(pipe);
		Customer customer = new Customer(pipe);
		
		new Thread(productor,"Productor").start();
		new Thread(customer,"Customer").start();
	}
}

//生产者
class Productor implements Runnable{
	PipeHandle pipe;
	
	public Productor(PipeHandle pipe) {
		super();
		this.pipe = pipe;
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		for(int i=0; i < 100; i++) {
			Food food = new Food();
			pipe.push(food);
			System.out.println("Productor is making " + i +" food");
		}
	}
	
}
//消费者
class Customer implements Runnable{
	PipeHandle pipe;
	
	public Customer(PipeHandle pipe) {
		super();
		this.pipe = pipe;
	}
	
	@Override
	public void run() {
		// TODO Auto-generated method stub
		for(int i=0; i < 100; i++) {
			Food food = pipe.pop();
			System.out.println("Coustomer is get "+i+" food");
		}
	}
	
}

//商品缓存区管道
class PipeHandle{
	Food[] pipe = new Food[10];
	int count;
	public PipeHandle( ) {
		
	}
	
	public synchronized void push(Food food) {
		if(count >= 10) {
			try {
				this.wait();
			} catch (InterruptedException e) {
			
			}
		}
		
		pipe[count++] = food;
        this.notifyAll();
	}
	
	public synchronized Food pop() {
		Food food = null;
		if(count == 0) {
			try {
				this.wait();
			} catch (InterruptedException e) {
			
			}
		}
		
		food = pipe[--count];
		this.notifyAll();

		return food;
	}
}

//商品
class Food{
	
}
发布了21 篇原创文章 · 获赞 0 · 访问量 1823
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章