初步认识多线程

为什么使用多线程-多线程的优势
1.使用多线程有可能提升效率

package package1212;

import java.util.Scanner;

public class Scene2 {
    //耗时比较慢的计算
    private static long fib(int n){
        if (n < 2){
            return n;
        }else {
            return fib(n - 1) + fib(n - 2);
        }
    }
    private static class MyThread extends Thread{
        private int n;
        
        MyThread(int n){
            this.n = n;
        }

        @Override
        public void run() {
            long result = fib(n);
            System.out.printf("fib(%d)的计算结果 %d%n",n,result);
        }
        
    }
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        while (true){
            System.out.println("请输入要计算的n : ");
            //主线程等着来客人,没人来之前一直在等
            int n = scanner.nextInt();
            //来了客人,就找了个人来干活
            Thread thread = new MyThread(n);
            thread.start();
        }
    }
}


某些场景下,主线程不允许做大量的计算,导致大量的计算必须放到多线程中
(GUI 图形界面开发)这个好玩
1.新建一个JavaFX文件
2.sample.fxml最后一行加个这语句

<Button text="点我" GridPane.columnIndex="0" GridPane.rowIndex="0" onAction="#onButton"/>

3.在Controller类中

package sample;

import javafx.fxml.FXML;

import javafx.event.ActionEvent;
public class Controller {
    @FXML public void onButton(ActionEvent actionEvent){
        System.out.println("hello world");

    }

}

如何创建多线程对象 Thread 对象

1.继承 Thread 类 + 覆写run方法
2.实现 Runnable 接口 + 覆写run方法
把Runnable 对象作为 Thread 类对象的参数
3.Thread 也实现了Runnable方法

使用场景:
通过1启动的线程对象,myThread 好处是在run方法中直接使用this代表当前线程对象
1的缺点:类的继承是单继承,


了解Thread的常见方法

1.获取线程的相关属性

package package1212;

public class ThreadFields {
    public static void main(String[] args) {
        //怎么获取到线程的相关对象
        //Thread.currentThread() 静态方法
        Thread currentThread = Thread.currentThread();
        System.out.println(currentThread.getId());
        System.out.println(currentThread.getName());
        System.out.println(currentThread.getPriority());
        System.out.println(currentThread.getState());
        System.out.println(currentThread.isDaemon());
        System.out.println(currentThread.isInterrupted());
        System.out.println(currentThread.isDaemon());
        System.out.println(currentThread.isInterrupted());
    }
}

.操作线程

1.启动一个线程 start() vs run()
2.A线程要B线程死


A线程要B线程去死

方法一:标志位法

package package1212;

public class HowThreadDie {
    private static class Worker extends Thread{
        private volatile boolean running = true;

        public void quit(){
            running = false;
        }

        @Override
        public void run() {
            while (running) {
                System.out.println("挖煤");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        Worker worker = new Worker();
        worker.start();
        Thread.sleep(10*1000);
        System.out.println("媳妇生了,赶紧回家");
        worker.quit();
        worker.join();//只有join了才是的真正回去
        System.out.println("他回去了");
    }
}

但是这种方法有种缺陷,worker.quit,老板说你媳妇生了,然后让你quit,但是工人还在休息(sleep)此时就GG了呀


interrupted(); A要B停

建议性终止
B怎么就知道A要B死
1.B正在睡眠(sleep/wait/join):通知是以异常的形式给到的:InterruptedException

//我在睡觉
package package1212;

public class HowThreadDie2 {
    private static class Worker extends Thread{


        @Override
        public void run() {
            while (true) {
                System.out.println("挖煤");
                try {
                    Thread.sleep(3*1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    break;
                }
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        Worker worker = new Worker();
        worker.start();
        Thread.sleep(10*1000);
        System.out.println("媳妇生了,赶紧回家");
        worker.interrupt();
        worker.join();//只有join了才真正回去
        System.out.println("他回去了");
    }
}

2.B没有在睡眠
2.1 isInterrupted()判断是否有人让我死,
2.2Thread.interrupted()

//我醒着,不睡觉
package package1212;

public class HowThreadDie2 {
    private static class Worker extends Thread{


        @Override
        public void run() {
            while (!Thread.interrupted()) {
                System.out.println("挖煤");
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        Worker worker = new Worker();
        worker.start();
        Thread.sleep(3*1000);
        System.out.println("媳妇生了,赶紧回家");
        worker.interrupt();
        worker.join();//只有join了才真正回去
        System.out.println("他回去了");
    }
}


总结:

普通方法 interru()通知线程停止
线程如果在休眠(sleep/wait/join),会受到 异常,状态保持false(不开灯泡)
线程如果没在休眠,则,状态位被修改为 true
线程可以通过 普通方法:isIntterrupted() 和静态 Thread.interrued() 判断
1.isInterrued()只获取当前状态,不会修改状态的值(不关灯)
2.Thread.interupeted() 获取当前线程状态,状态改为false(手贱关灯)

1.1 isInterrued() 任何线程都可以调用,只要有该线程的Thread对象
2.1 Thread.interrupted() 查看当前线程的状态

线程什么时候退出,或者不退出又线程自行决定.建议性的通知.

//我有可能在睡觉有可能醒着
private static class Worker extends Thread {
        @Override
        public void run() {
            //两种方式
            while (!Thread.interrupted()){//醒着的情况
                System.out.println("挖煤");
                try {
                    Thread.sleep(50*1000);
                } catch (InterruptedException e) {
                    break;//睡觉的情况
                }
            }
        }
    }

join()

A线程等待B线程退出
Thread b = …
b.start;
b.join;
sout(“一起走”); b线程已经结束了,从run方法中退出

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值