多线程详解 创建多线程

一. 进程与线程:

1. 进程:

进程是资源(CPU、内存等)分配的基本单位,它是程序执行时的一个实例。程序运行时系统就会创建一个进程,并为它分配资源,然后把该进程放入进程就绪队列,进程调度器选中它的时候就会为它分配CPU时间,程序开始真正运行。

2. 线程:

线程是一条执行路径,是程序执行时的最小单位,它是进程的一个执行流,是CPU调度和分派的基本单位,一个进程可以由很多个线程组成,线程间共享进程的所有资源,每个线程有自己的堆栈和局部变量。线程由CPU独立调度执行,在多CPU环境下就允许多个线程同时运行。同样多线程也可以实现并发操作,每个请求分配一个线程来处理。

3. 执行方式:

① 顺序执行:即程序从上往下一步一步的执行
② 并发执行:指两个或多个事件在同一个时间段内执行
③ 并行执行:指两个或多个事件在同一时刻同时执行

二. 创建多线程的三种方式:

1. 继承Thread类:

继承Thread类后要重写Thread类的run()方法,然后调用start()方法开启线程

public class TestThread1 extends Thread{     public static void main(String[] args){         EatThread eatThread= new EatThread();         DrinkThread drinkThread= new DrinkThread();         eatThread.start();         drinkThread.start();}}  class EatThread extends Thread{     @Override     public void run(){         System.out.println("开始吃饭?...\t" + new Date());         try{             Thread.sleep(5000);} catch(InterruptedException e){             e.printStackTrace();}         System.out.println("结束吃饭?...\t" + new Date());}}  class DrinkThread extends Thread{     @Override     public void run(){         System.out.println("开始喝酒?...\t" + new Date());         try{             Thread.sleep(5000);} catch(InterruptedException e){             e.printStackTrace();}         System.out.println("结束喝酒?...\t" + new Date());}}

此时的运行结果为:
多线程详解 创建多线程
当把主函数(即主线程)改为run()方法开启线程:

public class TestThread1 extends Thread{     public static void main(String[] args){         EatThread eatThread= new EatThread();         DrinkThread drinkThread= new DrinkThread();         eatThread.run();         drinkThread.run();}}

此时的运行结果为:
多线程详解 创建多线程
造成区别的原因时:当使用start()方法开启线程时,各线程是并发执行的,当使用run()方法开启线程时,各线程是顺序执行的。
多线程详解 创建多线程

2. 实现Runnable接口:

与继承Thread类方法类似,实现Runnable接口后要重写run()方法,然后使用Thread类来包装调用start()方法开启线程

public class TestThread2 implements Runnable{     @Override     public void run(){         System.out.println("开始吃饭?...\t" + new Date());         try{             Thread.sleep(5000);} catch(InterruptedException e){             e.printStackTrace();}         System.out.println("结束吃饭?...\t" + new Date());}      public static void main(String[] args){         TestThread2 t1= new TestThread2();         new Thread(t1).start();         Thread thread= new Thread(t1);  //对同一对象进行多线程从操作         thread.start();}}

运行结果为:
多线程详解 创建多线程

注意:newThread(t1).start();Threadthread=newThread(t1);thread.start();这两种写法效果是一样的第一种方法继承Thread类,Thread类也实现了Runnable接口第二种方法实现Runnable接口,类似创建一个代理工具类推荐使用实现Runnable接口的方法实现多线程,可以避免Java单线程的限制线程开启不一定立即执行,由CPU调度执行

3. 实现Callable接口:

① 实现Callable接口,需要返回值类型
② 重写call()方法,需要抛出异常
③ 创建目标对象 : TestThread3 testThread3 = new TestThread3()
④ 创建执行服务 : ExecutorService ser = Executors.newFixedThreadPool(2)
⑤ 提交执行 : Future r1 = ser.submit(testThread3)
⑥ 获取结果 : boolean rst1 = r1.get();
⑦ 关闭服务 : ser.shutdownNow();

public class TestThread3 implements Callable<Boolean>{  //①实现Callable接口,需要返回值类型     private String name;      public TestThread3(String name){         this.name= name;}     @Override     public Boolean call() throws Exception{  //②重写call()方法,需要抛出异常         if(name.equals("张三")){             System.out.println("欢迎"+name);returntrue;}returnfalse;}      public static void main(String[] args) throws ExecutionException, InterruptedException{         //③创建目标对象         TestThread3 t1= new TestThread3("张三");         TestThread3 t2= new TestThread3("李四");          //④创建执行服务         ExecutorService ser= Executors.newFixedThreadPool(2);          //⑤提交执行         Future<Boolean> r1= ser.submit(t1);         Future<Boolean> r2= ser.submit(t2);          //⑥获取结果         boolean rst1= r1.get();         boolean rst2= r2.get();         System.out.println(rst1);         System.out.println(rst2);          //⑦关闭服务         ser.shutdownNow();}}

运行结果:
多线程详解 创建多线程

三. 多线程实例——龟兔赛跑

public class Race implements Runnable{     private static String winner;     @Override     public void run(){for(int i= 1; i<= 100; i++){             // 模拟兔子休息             if(Thread.currentThread().getName().equals("兔子")&& i%10==0){                 try{                     Thread.sleep(100);} catch(InterruptedException e){                     e.printStackTrace();}}              boolean flag= isGameOver(i);             // 如果比赛结束,终止程序if(flag){break;}             // Thread.currentThread()获取当前线程             // Thread.currentThread().getName()获取当前线程名字             System.out.print(Thread.currentThread().getName()+"-->跑了"+i+"步"+"\t");             if(i%5==0)                 System.out.println();}}     // 判断是否有胜利者     public boolean isGameOver(int step){if(winner!=null){returntrue;}else{if(step>=100){                 winner= Thread.currentThread().getName();                 System.out.println("winner is "+winner);returntrue;}}returnfalse;}      public static void main(String[] args){         Race race= new Race();         new Thread(race,"兔子").start();         new Thread(race,"乌龟").start();}}

结果:
多线程详解 创建多线程
参考:https://blog.csdn.net/vbirdbest/article/details/81282163.