0%

Java-线程学习笔记(中)

线程学习笔记(中)

线程状态

thread
thread
  1. 新生状态
  2. 就绪状态
  3. 运行状态
  4. 阻塞状态
  5. 死亡状态

新生状态:用new关键字和Thread类或其子类建立一个线程对象后,该线程对象就处于新生状态。处于新生状态的线程有自己的内存空间,通过调用start方法进入就绪状态(runnable)
就绪状态:处于就绪状态的线程已经具备了运行条件,但还没有分配到CPU,处于线程就绪对列,等待系统为其分配CPU。等待状态并不是执行状态,当系统选定一个等待执行的Thread对象后,它就会从等待执行状态进入执行状态,系统挑选的动作称之为“CPU调度”。一旦获得CPU,线程就进入运行状态并自动调用自己的run()方法。
运行状态:在运行状态的线程执行自己的run方法中的代码,直到调用其他方法而终止、或等待某资源而阻塞或完成任务而死亡。如果在给定的时间片内没有执行结束,就会被系统给换下来回到等待执行状态。
阻塞状态:处于运行状态的线程在某些情况下,如执行了sleep方法,或等待I/O设备等资源,将让出CPU并暂时停止自己的运行,进入阻塞状态。在阻塞状态的线程不能进入就绪队列。只有当引起阻塞的原因消除时,如sleep时间已到,或等待的I/O设备空闲下来,线程便转入就绪状态,重新到时就绪对列中排队等待,被系统选中后从原来停止的位置开始继续运行。
死亡状态:死亡状态是线程生命周期中的最后一个阶段。线程死亡的原因有两个。一个是正常运行的线程完成了它的全部工作,另一个是线程被强制性地终止,如通过执行stop或destroy方法来终止一个线程(不推荐使用这两个方法,前者会产生异常,后者是强制终止,不会释放锁)

停止线程

1、自然终止:线程体正常执行完毕
2、外部干涉:
1)线程类中定义线程体使用的标识 2)线程体使用该标识 3)提供对外的方法改变该标识 4)外部根据条件调用该方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class StopDemo {
public static void main(String[] args){
Study s = new Study();
new Thread(s).start();
//外部干涉
for(int i=0;i<100;i++){
if(50==i)s.stop();
System.out.println("main...-->"+i);
}

}

}

class Study implements Runnable{
//线程类中定义线程体使用的标识
private boolean flag = true;
@Override
public void run() {
//线程体使用该标识
while(flag){
System.out.println("Study thread...");
}
}
//对外提供方法改变标识
public void stop() {
this.flag = false;
}
}

阻塞

  1. join:合并线程
  2. yield:暂停自己的线程 是一个静态的方法
  3. sleep:休眠,不释放锁 1)与时间相关:倒计时 2)模仿网络延迟
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class JoinDemo extends Thread{
public static void main(String[] args) throws InterruptedException {
JoinDemo demo = new JoinDemo();
demo.start();//就绪

for(int i=0;i<1000;i++){
/*
* demo.join()方法阻塞调用此方法的线程(calling thread),直到线程t完成,
* 此线程再继续;通常用于在main()主线程内,等待其它线程完成再结束main()主线程。
*/
if(i==50)demo.join();
System.out.println("main..."+i);
}
}

@Override
public void run() {
for(int i=0;i<1000;i++){
System.out.println("run..."+i);
}
}
}

线程的信息

isAlive() 判断线程是否还“活”着
getPriority() 获得线程的优先级数值
setPriority() 设置线程的优先级数值
setName() 设置线程的名字
getName() 获得线程的名字
currentThread() 取得当前正在运行的线程对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/**
* 〈优先级〉--代表的是概率,不是绝对的先后顺序
* 1、MAX_PRIORITY 10
* 2、NORM_PRIORITY 5(默认)
* 3、MIN_PRIORITY 1
* @author Zephon
*/
public class PriorityDemo {
public static void main(String[] args){
MyThread t1 = new MyThread("线程1");
MyThread t2 = new MyThread("线程2");
t1.setPriority(Thread.MAX_PRIORITY);
t2.setPriority(Thread.MIN_PRIORITY);
t1.start();
t2.start();
}
}
class MyThread extends Thread{

public MyThread(String name){
super(name);
}

@Override
public void run() {
for(int i=0;i<1000;i++)
System.out.println(currentThread().getName()+"running..."+i);
}
}