用于多任务的应用程序。
1、主线程
在每一个程序中,默认都有一个主线程,即main线程,它是程序的入口。
例1:
package demo;
/**
* 主线程
* @author xiangdonglee
*
*/
public class TestThread {
public static void main(String[] args) {
System.out.println("程序已经启动……");
for (int i = 0; i < 5; i++) {
// Thread.currentThread() 获得当前线程的引用
// Thread.getName() 获得线程的名字
System.out.println(Thread.currentThread().getName());
try {
Thread.sleep(1000); // 线程休眠
} catch (Exception e) {
e.printStackTrace();
}
}
System.out.println("程序结束……");
}
}
2、创建线程
方式1:extends Thread类
例2:
// 1. MyThread1.java
package demo;
public class MyThread1 extends Thread {
public MyThread1(String name) {
super(name);
}
/**
* run()方法:用来交代线程需要完成的任务
*/
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName());
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
// 2. TestMyThead1.java
package demo;
public class TestMyThread1 {
public static void main(String[] args) {
MyThread1 t1 = new MyThread1("线程1");
// t1.setName("线程1");
t1.start();
}
}
方式2:实现runnable接口
例3:
// 1. MyThread2.java
package demo;
public class MyThread2 implements Runnable{
@Override
public void run() {
for(int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
// 2. TestMyThread2.java
package demo;
public class TestMyThread2 {
public static void main(String[] args) {
// MyThread2 t2 = new MyThread2();
Thread t2 = new Thread(new MyThread2(), "线程2");
// t2.setName("线程2");
t2.start();
}
}
例4:烧水、洗杯子
// 1. WaterThread.java
package demo;
public class WaterThread extends Thread{
@Override
public void run() {
System.out.println("开始烧水");
try {
Thread.sleep(10000);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("水烧开了");
}
}
// 2. WashCupThread.java
package demo;
public class WashCupThread implements Runnable{
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("洗第" + (i+1) + "个杯子");
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
// Test.java
package demo;
public class Test {
public static void main(String[] args) {
WaterThread t1 = new WaterThread();
Thread t2 = new Thread(new WashCupThread());
t1.start();
t2.start();
}
}
3、结束线程
例5:
// 1. MyThread.java
package demo;
public class MyThread extends Thread{
private boolean bool = true;
public void setBool(boolean bool) {
bool = false;
}
@Override
public void run() {
while(bool) {
Thread.currentThread().getName();
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
// 2. Test.java
package demo;
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
MyThread t1 = new MyThread();
t1.setName("线程1");
t1.start();
// t1.stop(); // 不推荐使用
t1.setBool(false);
}
}
4、死锁
例:
// 1. DeadLockThread
package demo;
public class DeadLockThread extends Thread{
Object obj1 = null;
Object obj2 = null;
public DeadLockThread(Object obj1, Object obj2) {
this.obj1 = obj1;
this.obj2 = obj2;
}
@Override
public void run() {
// 同步块
synchronized (obj1) {
System.out.println("线程抢到了自己的资源");
System.out.println("然后再试图去抢占别人锁住的资源");
try {
Thread.sleep(1);
} catch (Exception e) {
e.printStackTrace();
}
synchronized (obj2) {
System.out.println("看看是否能进来");
}
}
}
}
// 2. TestDeadLockThread.java
package demo;
public class TestDeadLockThread {
public static void main(String[] args) {
Object obj1 = new Object(); // 枪
Object obj2 = new Object(); // 子弹
DeadLockThread t1 = new DeadLockThread(obj1, obj2); // t1先抢到枪
DeadLockThread t2 = new DeadLockThread(obj2, obj1); // t2先抢到子弹
t1.start();
t2.start();
}
}
5、线程的生命周期
线程的创建阶段:new出来。
线程的就绪阶段:start()之后进入就绪阶段。
线程的运行阶段:CPU决定谁进入运行阶段。
线程的死亡阶段:stop()之后进入死亡阶段;或者加boolean值来控制。
sleep():将运行阶段的线程拉到就绪阶段的等待队列。
interrupt():让正在睡觉的线程被吵醒。
t1.setDaemon(true):设置t1线程为后台线程。
后台线程:当程序中所有线程结束后,后台线程也会结束。
线程组 ThreadGroup:为了统一管理。