Java之理解线程

1 什么是线程

在一个程序之中可以,“同时”进行多个操作或者任务,而每一个任务就是一个线程,每一个线程完成一个功能,并且与其他线程并发执行,这种机制被称为线程。

2 理解线程

线程是进程中的一个顺序执行流(顺序执行流是有程序启动入口,程序逻辑和程序出口),线程是应用程序中的一个任务。(此任务完成了一个功能模块)

3 并发

3.1 理解并发

知道了什么是多线程,那么它是如何工作的呢?原理就是并发,不知道大家注意到没有,上面的“同时”,我是用引号标注的,因为他们并不是真正同时工作的,而是“轮流执行的”,这是什么意思呢?我举一个例子,大家可能就会明白的。

现有A线程和B线程,系统将时间分成等时间的时间片段,A线程需要四个时间片段才能完成,分别为【A1】,【A2】,【A3】,【A4】,B线程需要三个时间片段才能完成,分别是【B1】,【B2】,【B3】。

但是这7个时间片段的执行顺序是可以乱序的,在1-7个时间片段的时间内,可能是执行【A1】-》【B1】-》【A2】-》【B2】-》【A3】-》【B3】-》【A4】,也可能是【A1】-》【B1】-》【A2】-》【A3】-》【A3】-》【B2】-》【B3】,总之顺序是乱的,相当于在这几个时间片段中随机抽取一样,但是对于A线程和B线程会尽量让他们交替进行,而不是执行完一个在执行另一个。

由于时间片比较短暂,所以这种交替进行,在我们看来好像是“同时”进行的。在短短几毫秒之内执行完一个时间片段,有切换到下一个时间片段,这就是并发

3.2 并发的优点和缺点

优点--提高运行效率,(同时看两个电影,两个事情)

缺点--有安全隐患。比如同时访问一个txt文件,一个线程对这个txt进行写操作,一个进行读操作,那么这个读操作可能不会得到正确的结果,因为另一个线程在不断的写,还有如果多个同时访问一个“临界资源”(就是被synchronized修饰的),会出现死锁的问题

      

4 Java中的线程的生命周期

l  新建状态:就是new对象的过程,也就是在内存中分配内存。Thread t = newThread();

l  就绪状态:当此对象调用了start()方法,之后就进入就绪状态,此时线程进入一个就绪队列,分配时间片段,并等待获取执行权限,也就是轮到自己的时候运行。

l  运行状态:就是执行线程中run();方法内部代码的过程。

l  死亡状态:run方法执行结束,线程被销毁,也就是内存中的位置被清除,线程死亡。

l  阻塞状态:阻塞状态分三类:同步阻塞,等待阻塞,其他阻塞,这三种阻塞状态都是在运行状态的时候发生的,并且如果恢复,不是从当前被阻塞的运行状态恢复,而是回到就绪状态从新运行。

n  同步阻塞:就是当多个线程同时想要运行被synchronized修饰的方法,属性或者代码块的时候,会按照顺序一个一个的运行,而不会在“同时运行”,直到上一个线程运行结束,释放同步锁的时候,下一个线程会自动执行。此时阻塞的线程在锁池中等待。

n  等待阻塞:首先说明的是,等待阻塞一定是和synchronized配合使用的,表示将获取同步锁的线程放到等待池中(同步锁调用wait方法),注意:在等待池中的线程是不能自动释放的。只能是通过同步锁调用notify();或者notifyAll(),方法将等待池中的线程放入锁池中,然后按照锁池的方式来执行。

n  其他阻塞:就是当前线程停止运行,等待一定时间(sleep方法)或者等待当前线程运行结束(join方法)之后,立马回到就绪队列,准备继续运行。

5 Java线程的两种实现方式

5.1 继承Thread类

Thead类是Java.lang包下的一个类,从这个类中实例化的的对象,代表一个线程。程序员启动一个线程需要实例化一个Thread类的实例并且重写其中的run()方法。Thread类也是实现的runable接口的。

Ø  常用构造器摘要

表格 5‑1

构造方法

描述

Thread()

分配新的Thread对象

Thread(Runnable target)

分配新的Thread对象并指定目标

Thread(String name)

分配新的Thread对象并指定名字

Thread(Runnable target,String name)

分配新的Thread对象并指定目标和名字

Ø  常用方法摘要

注意:静态方法是全局共享的,和每一个对象无关,记住这一点很重要,静态方法,我说的都是“当前线程”,而普通方法,我说的都是“该线程”,注意体会其中的不同

表格 5‑2

返回值

方法名

描述

static Thread

currentThread()

返回当前线程的引用

long

getId()

返回该线程的标识符

String

getName()

返回该线程的名称

int

getPriority()

返回该线程的优先级,是从1到10,

void

interrupt

打断该线程,注意只有处于休眠状态的线程才会被打断,是打断的睡觉的线程,使该线程离开run方法,但程序会抛出InterruptedException异常,可以用来做逻辑判断

static boolean

interrupted

判断当前线程是否被打断

boolean

isAlive()

测试该线程是否处于活跃状态

boolean

isDaemon()

测试该线程是否是守护线程

boolean

isInterrupted()

测试该线程是否已经中断

void

join()

等待该线程终止,就是说如果在其他线程中,该线程调用了这个方法,那么其他线程,必须等待这个线程终止,才能继续运行

void

join(long millis)

同上,只不过是指定时间,单位为毫秒

void

run()

这个方法是线程的逻辑体,也就是说执行线程的时候,就是在执行这里面的内容。更加注意的一点是:!!!如果是使用自己指定的runable对象,也就是构造方法中的target,那么需要在这个run方法中,手动调用runable自己的run方法,否则将不会执行。

void

setDaemon(Boolean on)

将该线程设置为守护进程或者用户线程,如果on为true,则标记为守护线程

void

setName(String name)

设置或者改变该线程的名字

void

setPriority(int newPriority)

更改线程的优先级

static void

sleep(long millis)

在指定毫秒数内,让当前线程休眠,即停止运行

void

start()

使该线程开始执行:JAVA虚拟机调用run方法,注意!!!直接调用run方法,就不是线程了,也就是不具备线程的特性,并发!

Ø  一个小栗子


public class ThreadA extends Thread{
	private boolean isContinue = false;//通过一个布尔值来控制现场的结束和开始
	public void setContinue(boolean isContinue) {
		this.isContinue = isContinue;
	}
	public void run() {
		int count = 10;
		while(isContinue){
			System.out.println(getName()+":"+count--);
		}
	}
	public static void main(String[] args) {
		ThreadA a = new ThreadA();
		a.setContinue(true);
		a.start();	
	}
}

5.2 实现Runnable接口

Runnable接口只有一个方法,那么就是run()方法。

5.2.1    用Runnable的实现线程的用法

想要通过实现Runnable接口来使用线程,需要配合Thread类的两个构造方法来使用,那就是Thread(Runnable target)和Thread(Runnable target,String name),将其中的接口传入进去,那么实现接口中run方法的类中的逻辑,就会运行了,废话不多说。上代码

Ø  实现Runnable代码

/我又继承了Thread类的原因是,想用其中的get方法和其他一些方法,不要弄混
public class RunnableImpl extends Thread implements Runnable{

	@Override
	public void run() {
		System.out.println(getName()+"我是runable的实现类");
	}
	public static void main(String[] args) {
		Thread runnable1 = new Thread(new RunnableImpl());
		//第二个参数只是指定了当前对象的名字,而不是RunnableImpl(也就是target的名字)的名字
		Thread runnable2 = new Thread(new RunnableImpl(),"runnable2");
		runnable1.start();
		runnable2.start();
		System.out.println(runnable2.getName());
	}
}

运行结果:

       runnable2

      Thread-0我是runable的实现类

      Thread-2我是runable的实现类

6 说明:

本文只是讲解了其中的基本概念和常用方法,至于其中怎么用,我会在以后的文章中写出,文章的标题会告诉大家,我会写一些什么




猜你喜欢

转载自blog.csdn.net/swf_shixinshou/article/details/80652725
今日推荐