Java线程----初识线程
多线程:
(1) 概述:
进程是正在运行中的一个应用程序,线程是进程的最小处理单元,线程是进程的子集
线程是独立的,如果一个线程发生异常,不会影响其他线程的执行。
(2) 进程,线程的区别
地址空间:同一个线程共享本进程的地址空间,进程之间是独立的空间
线程是处理器调度的基本单位,而进程不是
进程可以独立运行,而线程不能独立运行,必须依存在应用程序中
(3) 线程的生命周期
新建--->就绪--->运行---->阻塞---->死亡
新建:当线程对象创建后,既进入新建状态
就绪:当调用线程对象的start()方法时,线程即进入了就绪状态
运行:当CPU开始调度处于就绪状态的线程时,此线程才真正执行,(线程要想进入运行状态,必须要处于就绪状态)
阻塞:处于运行状态的线程因为某种原因,暂时放弃对CPU的使用权,停止执行,此时进入阻塞状态;
死亡:线程执行完毕或者异常退出run()方法,该线程结束生命周期
(4) 创建:
继承自:java.lang.Thread类
实现自:java.lang.Runnable接口
实现自:java.util.concurrent.Callable接口
都是重写run()方法,使用Callable接口需要重写call()方法此方法是带有返回值的
(5) 使用:
继承Thread类:
重写run()方法,实例化该对象,使用该对象调用start()方法启动线程
启动多个线程时,同上,使用该对象的实例调用start()方法
例:
1 Public class TestThread extends Thread{ 2 3 4 5 //重写run()方法 6 7 @Override 8 9 Public void run(){ 10 11 //需要实现多线程的代码 12 13 } 14 15 16 17 //测试多线程,使用main方法 18 19 public static void main(String[] args){ 20 21 //实例化该对象 22 23 TestThread testThread=new TestThread(); 24 25 //调用start()方法启动一个线程 26 27 testThread.start(); 28 29 } 30 31 }
实现Runnable接口:
重写run()方法,实例化该对象,实例化Thread对象,并且调用Thread对象的有参构造函数,并把此类的实例化对象传入Thread对象中,调用实例化好的Thread对象的start()方法
例:
1 Public class TestRunnable implements Runnable{ 2 3 4 5 //重写run()方法 6 7 Public void run(){ 8 9 //需要实现多线程的代码 10 11 } 12 13 14 15 //使用main方法测试 16 17 Public static void main(String[] args){ 18 19 //先创建当前类的实例对象 20 21 TestRunnable testRunnable=new TestRunnable(); 22 23 //创建Thread对象 24 25 New Thread(testRunnable).start(); 26 27 } 28 29 }
实现callable接口
实现callable<明确返回值类型>接口,重写call()方法明确返回值类型,实例化此类,调用ExcutorService对象的带参构造方法创建执行服务,并在构造方法中传入要执行的几个线程,调用服务ExcutorService对象的submit()方法将线程对象添加进服务中,使用Future<返回值类型>对象提交执行,实行Future对象的git()方法返回结果,最后使用ExcutorService对象的shutdownNow()方法关闭服务
例:
1 Public class TestCallable implements callable<返回值>{ 2 3 //重写call()方法 4 5 @override 6 7 Public 返回值 call() throws Exception{ 8 9 //线程方法体 10 11 } 12 13 14 15 //mian方法测试线程需要抛出异常 16 17 Public static void main(String[] args){ 18 19 //创建线程对象 20 21 TestCallable testCallable=new TestCallable(); 22 23 //开启服务,明确线程个数 24 25 ExcutorService ser=Excutors.newFixedThreadPool(1); 26 27 //提交执行,向线程池中添加线程 28 29 Future<Integer> rs=ser.submit(testCallable); 30 31 //获得结果,其实就是获得call()方法的返回值 32 33 Integer rs1=rs.get(); 34 35 36 37 //关闭服务,其实就是关闭线程池 38 39 ser.shutdownNow(); 40 41 } 42 43 }
(6) 线程停止:
概述:线程停止就是线程在处理任务使,停掉当前正在做的操作,也就是放弃当前操作
方式:java有三种方式可以使线程停止
1. 使用stop方法,destroy方法强制终止线程(不推荐,被废弃了)
2. 使用标志位停止线程
3. 使用interrupt方法中断线程
实现方式:
使用标志位停止线程:
流程:
1.设置一个标志位,一般位boolean类型
2.创建一个线程停止方法,转换标志位,将boolean类型值改为false
3.当符合线程停止条件时调用线程停止方法
1 Public class TestStop implements Runnable{ 2 3 4 5 //1.设置一个标志位 6 7 private boolean flag=true; 8 9 10 11 public void run(){ 12 13 int i=0; 14 15 while(flag){ 16 17 System.out.println(“run….Thread”+i); 18 19 } 20 21 } 22 23 24 25 //2.创建一个线程停止方法 26 27 Public void stop(){ 28 29 This.flag=false; 30 31 } 32 33 34 35 //使用main方法测试线程停止 36 37 Public static void main(String[] args){ 38 39 //创建一个线程 40 41 TestStop testStop=new TestStop(); 42 43 //启动线程 44 45 New Thread(testStop).start(); 46 47 48 49 for(int i=0;i<=1000;i++){ 50 51 //设置线程停止条件 52 53 If(i==900){ 54 55 //使用停止方法停止线程 56 57 TestStop.stop(); 58 59 } 60 61 } 62 63 } 64 65 }
(7) 线程休眠:
概念:线程睡眠就是让线程先暂停或者延迟指定的时间再运行
方式:当前线程.sleep()
注意:每一个对象都有一把锁,sleep不会释放锁
应用场景:倒计时,模拟网络延迟等
例:
1 public class TestSleep implements Runnable { 2 3 4 5 // 模拟倒计时 6 7 @Override 8 9 public void run() { 10 11 int a = 10; 12 13 while (true) { 14 15 try { 16 17 Thread.currentThread().sleep(1000); 18 19 } catch (InterruptedException e) { 20 21 // TODO Auto-generated catch block 22 23 e.printStackTrace(); 24 25 } 26 27 System.out.println(a); 28 29 a--; 30 31 if(a<=0) { 32 33 break; 34 35 } 36 37 } 38 39 } 40 41 42 43 public static void main(String[] args) { 44 45 TestSleep testSleep=new TestSleep(); 46 47 new Thread(testSleep).start(); 48 49 } 50 51 }
(1) 线程礼让:
概念:
1.线程礼让就是让现在运行的线程先暂停,但不阻塞
2.线程从运行状态转为就绪状态
3.线程礼让不一定成功
实现:
1 public class TestYield { 2 public static void main(String[] args) { 3 //创建一个线程对象 4 Tyield tyield=new Tyield(); 5 //创建两个线程共用一个线程对象 6 new Thread(tyield,"a").start(); 7 new Thread(tyield,"b").start(); 8 } 9 } 10 11 class Tyield implements Runnable{ 12 13 public void run() { 14 System.out.println(Thread.currentThread().getName()+"线程开始"); 15 //当前线程礼让,不一定能成功 16 Thread.currentThread().yield(); 17 System.out.println(Thread.currentThread().getName()+"线程结束"); 18 } 19 }
结果:


浙公网安备 33010602011771号