多线程的调动是随着cpu调度的,可以给线程设置优先级,但最终还是要依靠CPU的调度,无法确定线程的执行顺序。
多线程的实现方法
-
-
实现Runnable接口,重写run()方法,执行线程需要丢入Runnable实现接口类,调用start方法;
-
实现Callable接口,并用其初始化Thread,然后创建Thread实例,并调用start方法。
详细说明
-
继承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的调度,无法确定线程的执行顺序。
-
实现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()方法时,就模拟了兔子的休息。此时乌龟仍然在跑。运行结果自然就大概率是乌龟是赢家。
-
实现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(); } }