zoukankan      html  css  js  c++  java
  • java线程专辑-基础篇

    线程的概念

    线程,有时被称为轻量级进程(Lightweight Process,LWP),是程序执行流的最小单元。一个标准的线程由线程ID,当前指令指针(PC),寄存器集合和堆栈组成。另外,线程是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源。一个线程可以创建和撤消另一个线程,同一进程中的多个线程之间可以并发执行。由于线程之间的相互制约,致使线程在运行中呈现出间断性。
    

    线程的生命周期

    这里写图片描述

    1. 新建状态(New):当线程对象对创建后,即进入了新建状态,如:Thread t = new MyThread();
    2. 就绪状态(Runnable):当调用线程对象的start()方法,线程即进入就绪状态。处于就绪状态的线程,只是说明此线程已经做好了准备,随时等待CPU调度执行,并不是说执行了t.start()此线程立即就会执行;
    3. 运行状态(Running):当CPU开始调度处于就绪状态的线程时,此时线程才得以真正执行,即进入到运行状态。注:就绪状态是进入到运行状态的唯一入口,也就是说,线程要想进入运行状态执行,首先必须处于就绪状态中
    4. 阻塞状态(Blocked):处于运行状态中的线程由于某种原因,暂时放弃对CPU的使用权,停止执行,此时进入阻塞状态,直到其进入到就绪状态,才有机会再次被CPU调用以进入到运行状态。根据阻塞产生的原因不同,阻塞状态又可以分为三种:
      1.等待阻塞:运行状态中的线程执行wait()方法,使本线程进入到等待阻塞状态;
      2.同步阻塞 -- 线程在获取synchronized同步锁失败(因为锁被其它线程所占用),它会进入同步阻塞状态;
      3.其他阻塞 -- 通过调用线程的sleep()或join()或发出了I/O请求时,线程会进入到阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。
    5. 死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。

    属性与方法分析

    1:线程优先级:
    java线程优先级默认继承父类,但可以通过setPriority();设置线程的优先级,java优先级等级为1-10,默认情况为5。但java线程的优先级高度依赖操作系统,当虚拟机依赖于宿主机平台的线程实现机制时,优先级个数可能会减少,或许会增加。
    主要方法:

    setPriority(int newPriority)
    
    static void	yield()
    

    该方法是给具有和自己相同或高于自己优先级的线程让步。

    2:守护线程:
    守护线程的主要用途是为其它线程服务,使用守护线程时,不能让它访问固有的资源,如文件、数据库,这是由于它随时可能中断。同时当虚拟机中只有守护线程时,虚拟机就退出了。

    thread.setDaemon(true);
    

    3:未捕获异常处理器
    线程的run方法不能抛出任何被检测的异常,但不被检测的异常会导致线程终止。
    java的该处理器必须属于一个实现Thread.UncaughtExceptionhandler 接口的类。这个接口只有一个方法,void uncaughtException(Thread t,Throwable e)

    import java.lang.Thread.UncaughtExceptionHandler;
    
    public class ThreadTest1 {
    
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
             Calculate calculate=new Calculate();
             calculate.setUncaughtExceptionHandler(new ErrorHandler());
             calculate.start();
    	}
       static class Calculate extends Thread
        {
        	public Calculate()
        	{
        		
        	}
        	public void run()
        	{
        		double i=10/0;
        		
        	}
        }
        
       static class ErrorHandler implements UncaughtExceptionHandler{
    
    		@Override
    		public void uncaughtException(Thread t, Throwable e) {
    			// TODO Auto-generated method stub
    			System.out.println("线程:"+t.getName()+",异常信息:"+e.getMessage());
    		}
        	
        }
    }
    

    运行结果:

    线程:Thread-0,异常信息:/ by zero
    

    若注释掉:calculate.setUncaughtExceptionHandler(new ErrorHandler());
    运行结果:

    Exception in thread "Thread-0" java.lang.ArithmeticException: / by zero
    	at com.csu.thread.ThreadTest1$Calculate.run(ThreadTest1.java:21)
    

    通过运行结果可以发现,线程将直接终止。
    我们在来看看子线程和父线程之间的异常关系,我们对上边的线程代码修改下:

    static class Calculate extends Thread
        {
        	public Calculate()
        	{
        		
        	}
        	public void run()
        	{
        		//double i=10/0;
        		Thread t=new Thread(new Runnable() {
    				
    				@Override
    				public void run() {
    					// TODO Auto-generated method stub
    					double i=10/0;
    				}
    			});
        		t.start();
        	}
        }
    

    运行结果:

    Exception in thread "Thread-1" java.lang.ArithmeticException: / by zero
    	at com.csu.thread.ThreadTest1$Calculate$1.run(ThreadTest1.java:27)
    	at java.lang.Thread.run(Thread.java:745)
    

    我们发现虚拟机直接报错,也就是说子线程的异常并没有传递给父线程。这样我们同样可以通过给线程设置:setUncaughtExceptionHandler

    线程基础实例

    1:线程创建的几种方法:

    • 继承Thread类
    • 实现Runnable接口
    • 通过Callable和Future创建线程
    import java.util.concurrent.Callable;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.FutureTask;
    
    public class ThreadTest1 {
    
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    		//方式1
             Calculate calculate=new Calculate();
             calculate.start();
             //方式2
             Thread t2=new Thread(new Runnable() {
    			
    			@SuppressWarnings("static-access")
    			@Override
    			public void run() {
    				// TODO Auto-generated method stub
    				try {
    					Thread.currentThread().sleep(10000);
    					System.out.println("通过方式2创建线程成功");
    				} catch (InterruptedException e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				}
    				
    			}
    		});
             t2.start();
             CallableThread ctt=new CallableThread();
             FutureTask<Integer> ft=new FutureTask<>(ctt);
             Thread t3= new Thread(ft,"可以获取返回值的thread");
             try {
    			System.out.println(ft.get());
    		} catch (InterruptedException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		} catch (ExecutionException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
             
    	}
       static class Calculate extends Thread
        {
        	public Calculate()
        	{
        		
        	}
        	@SuppressWarnings("static-access")
    		public void run()
        	{
        		
        		try {
    				this.sleep(10000);
    				System.out.println("通过方式1创建线程成功");
    			} catch (InterruptedException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
        		
        	}
        }
         static class CallableThread implements Callable<Integer>
         {
    
    		@Override
    		public Integer call() throws Exception {
    			// TODO Auto-generated method stub
    			int sum=0;
    			for(int i=0;i<100;i++)
    			{
    				sum+=i;
    			}
    			return sum;
    		}
        	 
         }
    }
    

    2:线程join() 等待指定线程死亡或指定时间后,再运行其它线程;

    public class ThreadTester {
    
    	public static void main(String[] args) throws InterruptedException {
    		// TODO Auto-generated method stub
    		Thread t1 = new Thread(new ThreadTesterA());
            Thread t2 = new Thread(new ThreadTesterB());
            t1.start();
            t1.join(); 
            t2.start();
            t2.join(); 
    
    	}
    	static class ThreadTesterA implements Runnable {
    		 
    	    private int counter;
    	 
    	    @Override
    	    public void run() {
    	        while (counter <= 10) {
    	            System.out.print("Counter = " + counter + " ");
    	            counter++;
    	        }
    	        System.out.println();
    	    }
    	}
    	 
    	static class ThreadTesterB implements Runnable {
    	 
    	    private int i;
    	 
    	    @Override
    	    public void run() {
    	        while (i <= 10) {
    	            System.out.print("i = " + i + " ");
    	            i++;
    	        }
    	        System.out.println();
    	    }
    	}
    
    }
    
  • 相关阅读:
    java OA系统 自定义表单 流程审批 电子印章 手写文字识别 电子签名 即时通讯
    flowable 获取当前任务流程图片的输入流
    最新 接口api插件 Swagger3 更新配置详解
    springboot 集成 activiti 流程引擎
    java 在线考试系统源码 springboot 在线教育 视频直播功能 支持手机端
    阿里 Nacos 注册中心 配置启动说明
    springboot 集成外部tomcat war包部署方式
    java 监听 redis 过期事件
    springcloudalibaba 组件版本关系
    java WebSocket 即时通讯配置使用说明
  • 原文地址:https://www.cnblogs.com/csuwater/p/5407180.html
Copyright © 2011-2022 走看看