您的位置:首页 > 编程语言 > Java开发

java线程——Thread类的使用

2016-07-08 15:51 537 查看
线程和进程的概念

进程的概念:

进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动。它是操作系统动态执行的基本单元,在传统的操作系统中,进程既是基本的分配单元,也是基本的执行单元。

线程的概念:

线程是程序执行流的最小单元。线程是程序中一个单一的顺序控制流程。进程内一个相对独立的、可调度的执行单元,是系统独立调度和分派CPU的基本单位指运行中的程序的调度单位。

线程的状态

     线程包括以下这几个状态:创建(new)、就绪(runnable)、运行(running)、阻塞(blocked)、消亡(dead)

当需要新起一个线程来执行某个子任务时,就创建了一个线程。但是线程创建之后,不会立即进入就绪状态,因为线程的运行需要一些条件(比如内存资源,在前面的JVM内存区域划分一篇博文中知道程序计数器、Java栈、本地方法栈都是线程私有的,所以需要为线程分配一定的内存空间),只有线程运行需要的所有条件满足了,才进入就绪状态。

当线程进入就绪状态后,不代表立刻就能获取CPU执行时间,也许此时CPU正在执行其他的事情,因此它要等待。当得到CPU执行时间之后,线程便真正进入运行状态。

线程在运行状态过程中,可能有多个原因导致当前线程不继续运行下去,比如用户主动让线程睡眠(睡眠一定的时间之后再重新执行)、用户主动让线程等待,或者被同步块给阻塞,此时就对应着多个状态:time waiting(睡眠或等待一定的事件)、waiting(等待被唤醒)、blocked(阻塞)。

当由于突然中断或者子任务执行完毕,线程就会被消亡。

多线程的实现方式

一种是继承Thread ,另外一种是实现Runnable接口。
public class MyThread extends Thread{
@Override
public void run() {
// TODO Auto-generated method stub
while(true) {
System.out.println("fuck ........java");
}
}
}

Runnable run = new Runnable() {

@Override
public void run() {
// TODO Auto-generated method stub
while(true) {
System.out.println("fuck...........java 1");
}
}
};
Thread t1 = new Thread(run);
t1.start();

Thread 有一些保存信息的属性,这些属性可以用来标示线程,显示线程的状态或者标示线程的优先级。

Id:线程的唯一标示

name:线程的名称

priority:线程的优先级

status:线程的状态

Thread常用的方法

①currentThread()方法
返回代码段正在被那个线程调用的信息。

public static void main(String[] args) {
System.out.println(Thread.currentThread().getName());
}
结果:

main

②isAlive()方法

判断当前线程是否处于活动状态,活动状态就是线程已启动尚未终止。

package com.test;

public class MyThread extends Thread{
@Override
public void run() {
System.out.println("run="+this.isAlive());
}
public static void main(String[] args) {
MyThread t = new MyThread();
System.out.println("begin="+t.isAlive());
t.start();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("end="+t.isAlive());
}
}


结果:

begin=false

end=true

run=false

③sleep()方法

在指定的毫秒数内让正在执行的当前线程休眠。

package com.test;

public class MyThread extends Thread{
@Override
public void run() {
System.out.println("begin");
try {
System.out.println(System.currentTimeMillis());
Thread.sleep(100);
System.out.println(System.currentTimeMillis());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("end");
}

public static void main(String[] args) {
MyThread t = new MyThread();
t.start();
}
}
结果:

begin

1467708456963

1467708457063

end

④getId()方法

取得线程的唯一标示。

public static void main(String[] args) {
Thread t = Thread.currentThread();
System.out.println(t.getId());
}
结果:

1

⑤stop()方法

停止线程,这个方法是不安全的,已过时,不建议在使用,

package com.test;

public class MyThread extends Thread{
private int i =0;
@Override
public void run() {
while(true) {
System.out.println(i++);
}
}

public static void main(String[] args) {
MyThread t = new MyThread();
System.out.println("线程开始");
t.start();
try {
t.sleep(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
t.stop();
System.out.println("停止线程");
}
}
结果:

......

9619

9620

9621

停止线程
⑥interrupted()或isInterrupted()

测试线程是否已经中断
两者的区别是interrupted 是作用于当前线程,isInterrupted 是作用于调用该方法的线程对象所对应的线程。(线程对象对应的线程不一定是当前运行的线程。例如我们可以在A线程中去调用B线程对象的isInterrupted方法。)interrupted()会清除线程的中断状态,换句话说它会改变interrupted的值为false,如果连续两次调用该方法,第二次返回false;

package com.test;

public class MyThread extends Thread{

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

public static void main(String[] args) {
MyThread t = new MyThread();
System.out.println("线程开始");
t.start();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
t.interrupt();
System.out.println("第一次是否停止:"+t.interrupted());
System.out.println("第二次是否停止:"+t.interrupted());
}
}


打印结果:

线程开始

0

1

.........

408

第一次是否停止:false

409
.............

573

第二次是否停止:false

574

..........

public static void main(String[] args) {
MyThread t = new MyThread();
System.out.println("线程开始");
t.start();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
t.interrupt();
System.out.println("第一次是否停止:"+t.isInterrupted());
System.out.println("第二次是否停止:"+t.isInterrupted());

}
打印结果:

第一次是否停止:true

第二次是否停止:true

⑦interrupt()

用于中断线程。调用该方法的线程的状态为将被置为"中断"状态

线程中断仅仅是置线程的中断状态位,不会停止线程。需要用户自己去监视线程的状态为并做处理。我们通常用isInterrupted()去判断是否中断线程,如果为true,则中断

if(isInterrupted())
{

return
;

}

public class InterThread extends Thread{

@Override
public void run() {
// TODO Auto-generated method stub
super.run();
for(int i=500000;i>0;i--){
System.out.println(Thread.currentThread().getName()+"——>"+i);
}
}

public static void main(String[] args) {
InterThread t = new InterThread();
t.start();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
t.interrupt();
System.out.println("是否停止——>"+t.interrupted());
t.stop();

}

}
输出结果:

.............

Thread-0——>499720

是否停止——>false

Thread-0——>499719

Thread-0——>499718

...............

可以看出线程并没有停止

⑧suspend()和resume()

suspend()挂起线程,已过时,会造成死锁

resume()是线程重新回到可执行状态,已过时,配合suspend()使用

package com.test;

public class SRThread extends Thread{

@Override
public void run() {
// TODO Auto-generated method stub
int i=0;
super.run();
while(true) {
System.out.println(i++);
}
}

public static void main(String[] args) {
SRThread t = new SRThread();
t.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
t.suspend();
System.err.println("当前时间戳------------------------"+System.currentTimeMillis());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.err.println("当前时间戳------------------------"+System.currentTimeMillis());
t.resume();

}
}
结果:

......

125541

当前时间戳------------------------1467962355695

当前时间戳------------------------1467962356695

125442

.........

⑨yield()

暂停当前正在执行的线程对象,并执行其他线程

package com.test;

import org.omg.PortableInterceptor.SYSTEM_EXCEPTION;

public class YeildTest  extends Thread{
@Override
public void run() {
// TODO Auto-generated method stub
long s = System.currentTimeMillis();
super.run();
for(int i=500000;i>0;i--){
//Thread.yield();
System.out.println(Thread.currentThread().getName()+"——>"+i);
}
long e = System.currentTimeMillis();
System.out.println((e-s)+"毫秒");
}

public static void main(String[] args) {
YeildTest yt = new YeildTest();
yt.start();
}

}


结果:

6707毫秒

去掉下面一行的注释

//Thread.yield();


结果:

8139毫秒


setPriority(int newPriority)

更改线程的优先级。优先级较高的线程得到CPU资源多,也就是CPU优先执行优先级高的线程。

public class YeildTest  extends Thread{
@Override
public void run() {
// TODO Auto-generated method stub
long s = System.currentTimeMillis();
super.run();
for(int i=500000;i>0;){
i--;
}
long e = System.currentTimeMillis();
System.out.println(getName()+":"+(e-s)+"毫秒");
}

public static void main(String[] args) {
YeildTest yt = new YeildTest();
yt.setPriority(10);
yt.start();
YeildTest yt1 = new YeildTest();
yt1.setPriority(1);
yt1.start();
}

}


结果:
Thread-0:1毫秒

Thread-1:7毫秒

⑪setDaemon

将该线程标记为守护线程或用户线程。必须在启动线程前调用。
示例:
package com.sh;

public class MyThread extends Thread{

private int i=0;

@Override
public void run() {
while(true) {
System.out.println(i++);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

public static void main(String[] args) {
MyThread mt = new MyThread();
mt.setName("A");
mt.setDaemon(true);
mt.start();
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("main end!");
}
}
打印结果:
..............
28

29

main end!
可以看出main方法结束后就不在打印了

⑫join
是用来指定当前主线程等待其他线程执行完毕后,再来继续执行Thread.join()后面的代码


package com.sun.test.join;
/********************************************************************
join是用来指定当前主线程等待其他线程执行完毕后,再来继续执行Thread.join()后面的代码。
***********************************************************************/
public class MyThread extends Thread{
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("-------子线程"+Thread.currentThread().getName()+"开始执行-----------");

try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("---------子线程"+Thread.currentThread().getName()+"结束执行----------");
}

public static void main(String[] args) {
MyThread myThread = new MyThread();
Thread t1 = new Thread(myThread,"t1");
t1.start();
try {
t1.join();
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
Thread t2 = new Thread(myThread,"t2");
t2.start();
try {
t2.join();
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
Thread t3 = new Thread(myThread,"t3");
t3.start();
try {
t3.join();
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}

System.out.println("------主线程执行完毕----------");

//结果线程执行顺序t1,t2,t3
}
}


打印结果:
-------子线程t1开始执行-----------

---------子线程t1结束执行----------

-------子线程t2开始执行-----------

---------子线程t2结束执行----------

-------子线程t3开始执行-----------

---------子线程t3结束执行----------

------主线程执行完毕----------

以上就是thread 常用的方法
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: