Java多线程的应用

多线程的调动是随着cpu调度的,可以给线程设置优先级,但最终还是要依靠CPU的调度,无法确定线程的执行顺序。

多线程的实现方法

  • 继承Thread类,重写run()方法,调用start开始线程;

  • 实现Runnable接口,重写run()方法,执行线程需要丢入Runnable实现接口类,调用start方法;

  • 实现Callable接口,并用其初始化Thread,然后创建Thread实例,并调用start方法。

详细说明

  1. 继承Thread类

  

//创建线程方式一:继承Thread类,重写run()方法,调用start开始线程
public class demo1 extends Thread {
    @Override
    public void run() {         //重写run方法
        for (int i = 0; i <= 99; i++) {
            System.out.println(i+"在学习多线程");
        }
    }
    public static void main(String[] args) {
​
        demo1 thread = new demo1();     
        thread.start();                 //启动run方法
​
        for (int i = 0; i <= 99; i++) {
            System.out.println("主方法"+i+"也在学习多线程");
        }
    }
}

  

Thread本质上也是实现了Runnable接口的一个实例,它代表一个线程的实例,启动线程的唯一方法就是通过Thread类的start()实例方法。执行结果是随着cpu调度的,可以给线程设置优先级,但最终还是要依靠CPU的调度,无法确定线程的执行顺序。

  1. 实现Runnable接口

public class demo4 implements Runnable {
    private int ticketNum = 10;
​
    @Override
    public void run() {     //重写run方法
        while (true){
            if (ticketNum<=0){
                break;
            }
            System.out.println(Thread.currentThread().getName() + "拿走了第"+ ticketNum + "票。");
            ticketNum--;
        }
    }
    public static void main(String[] args) {
        demo4 t1 = new demo4();
        demo4 t2 = new demo4();
        demo4 t3 = new demo4();
​
        new Thread(t1,"Jeri").start();      //执行线程
        new Thread(t2,"Jordon").start();
        new Thread(t3,"Knight").start();
    }
}

  

当自己的类已经继承(extends)了另一个类,就无法再次extends Thread。此时,必须实现一个Runnable接口,如上所示。但实现Runnable接口的线程执行与extends Thread有所不同,需要new一个Thread对象,再把线程丢入,最后start.

举一个龟兔赛跑的例子,乌龟不停跑,兔子偶尔会休息:

//龟兔赛跑模拟
public class demo5_race implements Runnable {
    private static String winner;
    @Override
    public void run() {
        for (int i = 0; i <= 100; i++) {
            //如果是兔子,就让他休息1ms,下面的条件表示的是i是10的倍数时兔子再休息
            if (Thread.currentThread().getName().equals("兔子") && i % 10 ==0){
                try {
                    Thread.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            //判断是否有胜利者出现了
            boolean flag = gameOver(i);
            if (flag){
                break;
            }
            System.out.println(Thread.currentThread().getName() + "跑了" + i + "步");
        }
    }
    //判断比赛是否结束了
    public boolean gameOver(int step){
        if (winner != null){
            return true;
        }{
            if (step >= 100){
                winner = Thread.currentThread().getName();
                System.out.println(winner + " is winner!");
                return true;
            }
        }
        return false;
    }
    //主函,两个线程
    public static void main(String[] args) {
        demo5_race race = new demo5_race();
        new Thread(race,"乌龟").start();
        new Thread(race,"兔子").start();
    }
}

  

当使用Thread.sleep()方法时,就模拟了兔子的休息。此时乌龟仍然在跑。运行结果自然就大概率是乌龟是赢家。

  1. 实现Callable接口

package thread;
​
import java.util.concurrent.*;
​
public class demo6_callable implements Callable<Boolean> {
    @Override
    public Boolean call() throws Exception {
        for (int i = 0; i < 10; i++) {
            System.out.println(Thread.currentThread().getName()+"call方法的线程正在跑...");
        }
        return true;
    }
​
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        for (int i = 0; i < 10; i++) {
            System.out.println(Thread.currentThread().getName()+"主方法的线程...");
        }
​
        demo6_callable demo6 = new demo6_callable();
​
        //创建执行服务
        ExecutorService ser = Executors.newFixedThreadPool(3);
        //提交执行
        Future<Boolean> sub = ser.submit(demo6);
        //获取结果
        Boolean aBoolean = sub.get();
        //关闭服务
        ser.shutdown();
    }
}

  


 

原文地址:https://www.cnblogs.com/awong18/p/14370318.html