Java标准库中提供Thread类来表示线程。
一、线程创建
1、继承 Thread, 重写 run
package Thread;
class MyThread extends Thread{
public void run(){
while(true){
System.out.println("hello thread");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Demo1 {
public static void main(String[] args) throws InterruptedException {
MyThread myThread=new MyThread();
myThread.start();
while(true){
System.out.println("hello main");
Thread.sleep(1000);
}
}
}
2、实现 Runnable, 重写 run
package Thread;
class MyRunnable implements Runnable{
@Override
public void run() {
while(true){
System.out.println("hello thread ");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Demo2 {
public static void main(String[] args) throws InterruptedException {
MyRunnable myRunnable=new MyRunnable();
Thread thread=new Thread(myRunnable);
thread.start();
while(true){
System.out.println("hello main");
Thread.sleep(1000);
}
}
}
3、继承 Thread, 重写 run, 使用匿名内部类
package Thread;
public class Demo3 {
public static void main(String[] args) throws InterruptedException {
Thread t=new Thread(){
@Override
public void run() {
while (true){
System.out.println("hello thread");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
t.start();
while(true){
System.out.println("hello main");
Thread.sleep(1000);
}
}
}
4、实现 Runnable, 重写 run, 使用匿名内部类
package Thread;
public class Demo4 {
public static void main(String[] args) throws InterruptedException {
Thread t=new Thread(new Runnable(){
@Override
public void run() {
while (true){
System.out.println("hello thread");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
t.start();
while(true){
System.out.println("hello main");
Thread.sleep(1000);
}
}
}
5、使用 lambda 表达式
package Thread;
public class Demo5 {
public static void main(String[] args) throws InterruptedException {
Thread t=new Thread(()->{
while(true){
System.out.println("hello thread");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t.start();
while(true){
System.out.println("hello main");
Thread.sleep(1000);
}
}
}
二、终止线程
线程的run方法执行完毕,这个线程就终止了
1、手动设置标志位
由于lambda会进行变量捕获,故标志位需设置为成员变量而不是局部变量
package Thread;
public class Demo6 {
//将标志位isQuit设置为成员变量
public static boolean isQuit=false;
public static void main(String[] args) throws InterruptedException {
Thread t=new Thread(()->{
while (!isQuit){
System.out.println("hello thread");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t.start();
Thread.sleep(4000);
isQuit=true;
System.out.println("线程t结束");
}
}
2、使用Thread类自动设置标志位
package Thread;
public class Demo7 {
public static void main(String[] args) throws InterruptedException {
Thread t=new Thread(()->{
while(!Thread.currentThread().isInterrupted()){
System.out.println("hello thread");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
//e.printStackTrace();
break;
}
}
});
t.start();
Thread.sleep(3000);
t.interrupt();
System.out.println("t线程结束");
}
}
三、线程等待
使用join方法
A、B两个线程,要b先结束,A后结束,让A使用join方法
package Thread;
public class Demo8 {
public static void main(String[] args) {
Thread B=new Thread(()->{
for (int i=0;i<5;i++){
System.out.println("hello B");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("B线程结束");
});
Thread A=new Thread(()->{
for (int i=0;i<3;i++){
System.out.println("hello A");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
B.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("A线程结束");
});
A.start();
B.start();
}
}
四、线程休眠
采用sleep方法
sleep方法的单位是毫秒,但sleep本身会存在误差,sleep(1000)并不就是准确的休眠1秒钟。
特殊用法:sleep(0)表示让当前线程放弃CPU从而进行下一轮调度,与yield方法的效果相同。