一.问题
1.程序代码一般都是顺序执行的,如何让程序在运行过长中,实现多个代码段的同时运行?
2.如何创建一个线程?创建线程的两种方式分别是什么?
3.线程为什么要休眠?
4.Thread类都有哪些方法?
5.如何实现线程内部的数据共享?
二.目标
1.学习java中线程的使用
2.掌握线程的调度和控制方法
三.Thread 类创建线程
1.通过Thread类创建线程
Thread类
·直接继承了Object类,并实现了Runnable接口。位于java.lang包中
·封装了线程对象需要的属性和方法
2.继承Thread类--创建多线程的方法之一
·从Thread类派生一个子类,并创建子类的对象
·子类应该重写Thread类的run方法,写入需要在新线程中执行的语句段。
·调用start方法来启动新线程,自动进入run方法。
在新线程中完成计算
public class FactorialThread extends Thread {
private int num;
public FactorialThread(int num){
this.num=num;
}
@Override
public void run() {
int i = num;
int result=1;
System.out.println("new thread started");
while (i>0){
result = result*i;
i=i-1;
}
System.out.println("the factorial of "+num+"is "+result);
System.out.println("new thread ends");
}
}
public static void main(String[] args) {
System.out.println("main thread starts");
FactorialThread thread = new FactorialThread(10);
thread.start();
System.out.println("main thread ends");
}
3.结果说明
·main 线程已经执行完成,新线程才执行完
·main方法调用thread.start()方法启动新线程后并不等待run方法返回就继续运行,线程的run方法在一边独自运行,不影响原来的main方法的运行
4.修改:延长主线程
·如果启动新线程后希望主线程多持续一会在结束,可在start 语句后加上当前线程(这里当然是main)休眠1毫秒的语句:
public static void main(String[] args) {
System.out.println("main thread starts");
FactorialThread thread = new FactorialThread(10);
thread.start();
try {
Thread.sleep(1000);
}catch (Exception e){
}
System.out.println("main thread ends");
}
5 创建3个新线程,每个线程睡眠(0~6秒),然后结束
public static void main(String[] args) {
TestThread thread1 = new TestThread("thread1");
TestThread thread2 = new TestThread("thread2");
TestThread thread3 = new TestThread("thread3");
System.out.println("starting threads");
thread1.start();
thread2.start();
thread3.start();
System.out.println("Threads started , main ends\n");
}
public class TestThread extends Thread {
private int sleepTime;
public TestThread(String name) {
super(name);
sleepTime = (int)(Math.random()*6000);
}
@Override
public void run() {
try {
System.out.println(getName()+"going to sleep for "+sleepTime);
Thread.sleep(sleepTime);
}catch (InterruptedException exception){
}
System.out.println(getName()+"finished");
}
}
·运行结果
starting threads
Threads started , main ends
thread1going to sleep for 1809
thread2going to sleep for 1568
thread3going to sleep for 775
thread3finished
thread2finished
thread1finished
·说明
1.由于线程 休眠时间最长,所以最后结束,线程 休眠时间最短,所以最先结束
2.每次运行,都会产生不同的随机休眠时间,所以结果都不相同
Thread类--常用API方法
名称 | 技能 |
---|---|
public Thread() | 构建一个新的线程对象,默认名为Thread-n ,n是从0开始递增的整数 |
public Thread (Runnable target) | 构造一个新的线程对象,以一个现实Runnable接口的类的对象为参数。默认名为Thread-n ,n是从0开始递增的整数 |
public Thread (String name) | 构造一个新的线程对象,并同时制定线程名 |
public static Thread currentThread | 返回当前正在运行的线程对象 |
public static void yieId() | 使当前线程对象暂停,允许别的线程开始运行 |
public static void sleep(long millis) | 使当前线程暂停运行制定毫秒数,但此线程并不失去已获得的锁。 |
public void start() | 启动线程,jvm将调用此线程的run方法,结果是将同时运行两个线程,当前线程和执行run方法的线程 |
public void run() | Thread 的子类应该重写此方法,内容应为该线程应执行的任务 |
public final void stop() | 停止线程运行,释放该线程占用的对象锁 |
public void interrupt() | 中断此线程 |
public final void join() | 如果此前启动了线程A,调用join方法将等待线程A死亡才能继续执行当前线程 |
public final void join(long millis) | 如果此前启动了线程A,调用join方法将等待指定毫秒数或者线程A死亡才能继续执行当前线程 |
public final void setPriority(int newPriority) | 设置线程优先级 |
pubic final void setDaemon(Booleanon) | 设置是否为后台线程,如果当前运行线程均为后台线程则jvm停止运行。这个方法必须在start()方法前使用 |
public final void checkAccess() | 判断当前线程是否有权力修改调用此方法的线程 |
public void setName(String name) | 更改本线程的名称为指定参数 |
public final boolean isAlive() | 测试线程是否处于活动状态,如果线程被启动并且没有死亡则返回true |
四、通过Runable接口构造线程
1.Runable接口
·只有一个run()方法
·Thread类实现了Runable接口
· 便于多个线程共享资源
· java不支持多继承,如果已经继承了某基类,便需要实现Runable接口来生成多线程
· 已实现Runable的对象为参数建立新的线程
· start 方法启动线程就会运行run()方法
2.使用Runable接口实现上面单线程的例子
public static void main(String[] args) {
System.out.println("mian thread starts");
FactorialThread thread = new FactorialThread(10);
new Thread(thread).start();
System.out.println("new thread started ,main thread ends");
}