线程
1. 线程的概述:
1. 单线程程序: 这个程序只有一个执行流程,所以这样的程序就是单线程程序。
2. 多线程程序: 假如一个程序有多条执行流程,那么,该程序就是多线程程序。
3. 线程是程序中单个顺序的控制流,是程序使用CPU的基本单位。
4. 先了解一下进程:
进程指正在运行的程序,是系统进行资源分配和调用的独立单位,每一个进程都有
5. 进程与线程的关系:
一个进程如果只有一条执行路径,则称为单线程程序。一个进程如果有多条执行路径,则称为多线程程序。
6. JVM虚拟机的启动是是多线程的。
2.多线程的实现方案
—第一种实现多线程的方法 通过继承Thread类
例如:我们输出0-19之间的整数!
public class Test6 {
public static void main(String[] args) {
ThreadDemo t = new ThreadDemo();
t.start();//这里调用start时,会先向jvm发送一个信号,jvm会开一个子线程,调用t里面的run方法!
//t.run();在这里不能直接调用run方法,要是直接调用就没有实现run方法。
System.out.println("我是神");
}
}
class ThreadDemo extends Thread{
//继承Thread时要重写Thread里面的run方法
@Override
/**
* 输入1-20之间的整数
*/
public void run() {
for (int i = 0; i < 20; i++) {
System.out.println(i);
}
}
}
上面的打印结果为:
我是神
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
附加:
- 如何获取和更改线程的名字:
//public final void setName(String name)
更改线程的名字:t . setName(“线程一”);
//public final String getName()
获取线程的名字:t . getName(); - 还可以通过构造方法更改名字
Thread.currentThread().getName();//获取当前所在线程的名字
ThreadDemo t = new ThreadDemo("x线程1");
public ThreadDemo(String name) {
super(name);
}
—第二种实现多线程的方法 通过实现接口Runnable
我们还是通过打印0-19之间的整数
public class Teat7 {
public static void main(String[] args) {
//在这里我们先声明一个该类,然后通过Thread来接受这个类,实现线程的启动
ThreadDemo t = new ThreadDemo();
new Thread(t).start();
System.out.println("我是神");
}
}
class ThreadDemo7 implements Runnable {
@Override
public void run() {
for (int i = 0; i < 20; i++) {
System.out.print(i + " ");
}
}
}
输出结果:
我是神
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
附加:
1. 如何获取和更改线程的名字:
new Thread(t,"线程2").start();//这里直接给了更改名字的方法
Thread.currentThread().getName();//获取当前所在线程的名字
2.线程的控制
——-2.1线程的阻塞
public static void sleep(long millis)//线程睡眠
public static void main(String[] args) {
ThreadDemo t = new ThreadDemo("线程1");
System.out.println(t.getName());
t.start();//这里调用start时,会先向jvm发送一个信号,jvm会开一个子线程,调用t里面的run方法!
//t.run();在这里不能直接调用run方法,要是直接调用就没有实现run方法。
try {
t.sleep(100);//这里不是指线程一睡眠100毫秒,是指当前线程睡眠100毫秒,也就是t线程在哪个线程执行,哪个线程睡眠
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("我是神");
}
}
class ThreadDemo extends Thread{
public ThreadDemo(String name) {
super(name);
}
//继承Thread时要重写Thread里面的run方法
@Override
/**
* 输入1-20之间的整数
*/
public void run() {
for (int i = 0; i < 20; i++) {
System.out.print(i+" ");
}
System.out.println();
}
}
输出结果
线程1
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
我是神
public final void join()// 等待
先让t所在的线程先执行完,当前所在的线程再执行/
public class Test6 {
public static void main(String[] args) {
ThreadDemo t = new ThreadDemo("线程1");
System.out.println(t.getName());
t.start();//这里调用start时,会先向jvm发送一个信号,jvm会开一个子线程,调用t里面的run方法!
//t.run();在这里不能直接调用run方法,要是直接调用就没有实现run方法。
try {
t.join();//t先执行完。当前所在的线程才会执行
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("我是神");
}
}
class ThreadDemo extends Thread{
public ThreadDemo(String name) {
super(name);
}
//继承Thread时要重写Thread里面的run方法
@Override
/**
* 输入1-20之间的整数
*/
public void run() {
for (int i = 0; i < 20; i++) {
System.out.print(i+" ");
}
System.out.println();
}
}
public static void yield()//暂停当前的线程
public class Test6 {
public static void main(String[] args) {
ThreadDemo t = new ThreadDemo("线程1");
System.out.println(t.getName());
t.start();//这里调用start时,会先向jvm发送一个信号,jvm会开一个子线程,调用t里面的run方法!
//t.run();在这里不能直接调用run方法,要是直接调用就没有实现run方法。
try {
t.yield();//t线程暂停
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("我是神");
}
}
class ThreadDemo extends Thread{
public ThreadDemo(String name) {
super(name);
}
//继承Thread时要重写Thread里面的run方法
@Override
/**
* 输入1-20之间的整数
*/
public void run() {
for (int i = 0; i < 20; i++) {
System.out.print(i+" ");
}
System.out.println();
}
}
输出结果
线程1
我是神
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
——-2.1线程的中断
public final void stop()//
我们在这里不用stop ,stop有安全隐患,我们通过设置一个boolean类型来控制停止
public class Teat7 {
public static void main(String[] args) {
//在这里我们先声明一个该类,然后通过Thread来接受这个类,实现线程的启动
ThreadDemo7 t = new ThreadDemo7();
new Thread(t).start();
t.stop();
//Thread.currentThread().getName();
System.out.println("我是神");
}
}
class ThreadDemo7 implements Runnable {
private boolean isfalg = false;
public void stop() {
isfalg = true;
}
@Override
public void run() {
if(isfalg) {
return;
}
for (int i = 0; i < 20; i++) {
System.out.print(i + " ");
}
}
}
public void interrupt ()
sleep + interrupt 的使用
public class Test6 {
public static void main(String[] args) {
ThreadDemo t = new ThreadDemo("线程1");
System.out.println(t.getName());
t.start();//这里调用start时,会先向jvm发送一个信号,jvm会开一个子线程,调用t里面的run方法!
//t.run();在这里不能直接调用run方法,要是直接调用就没有实现run方法。
t.interrupt();
System.out.println("我是神");
}
}
class ThreadDemo extends Thread{
public ThreadDemo(String name) {
super(name);
}
//继承Thread时要重写Thread里面的run方法
@Override
/**
* 输入1-20之间的整数
*/
public void run() {
try {
sleep(1000);
} catch (InterruptedException e) {
System.out.println("睡眠终止");
}
for (int i = 0; i < 20; i++) {
System.out.print(i+" ");
}
System.out.println();
}
}
结果:
线程1
我是神
睡眠终止
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
– join + interrupt
package cn.TeacherXu;
public class Test6 {
public static void main(String[] args) {
ThreadDemo t = new ThreadDemo("线程1", Thread.currentThread());
System.out.println(t.getName());
t.start();// 这里调用start时,会先向jvm发送一个信号,jvm会开一个子线程,调用t里面的run方法!
// t.run();在这里不能直接调用run方法,要是直接调用就没有实现run方法。
try {
t.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// t.interrupt();// public void interrupt()当前线程如果是阻塞状态,调用interrupt方法之后阻塞状态将会中断,
//还会受到一个InterruptedException
//Thread.currentThread().interrupt();//不能放在这里中断主线程,因为t.join一执行,整个主线程就已经进入阻塞状态
System.out.println("我是神");
}
}
class ThreadDemo extends Thread {
private Thread mainThread;
public ThreadDemo(String name, Thread mainThread) {
super(name);
this.mainThread = mainThread;
}
// 继承Thread时要重写Thread里面的run方法
@Override
/**
* 输入1-20之间的整数
*/
public void run() {
try {
sleep(100);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mainThread.interrupt();
for (int i = 0; i < 20; i++) {
System.out.print(i + " ");
}
System.out.println();
}
}