• Java总结之线程(1)


    java线程是很重要的一项,所以作为java程序员必须要掌握的。

    理解java线程必须先理解线程在java中的生命周期。、

    1.java线程生命周期

    1.new  创建一个线程  java中创建线程有三种方式,1.继承Thread类,2.继承Runnable接口,然后重写父类的run方法。

    2.Runnable  线程处于就绪状态,随时可以被cpu调用。

    3.Running 线程处于运行状态,此时线程正在CPU中执行。

    4.Blocked 线程处于阻塞状态,由于某种原因,cpu暂时中断线程的资源。只有线程再次进入就绪状态才能重新被cpu调用,同时阻塞有三种状态

        (1)等待阻塞:运行状态中的线程执行wait方法,使本线程进入等待阻塞状态。

        (2)同步阻塞:线程在获取synchronized同步锁失败(因为锁被其它线程所占用),它会进入同步阻塞状态;

        (3)其他阻塞:通过调用线程的sleep()或join()或发出了I/O请求时,线程会进入到阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。  

         (4)死亡状态:线程运行完毕或因异常终止线程,该线程结束生命周期。  

    2.线程的三种创建方式

     (1) 继承Thread类

    public class MyThread extends Thread{
    	
    	
    	
    	public MyThread(String name){
    		super(name);
    	}
    	
    	@Override
    	public void run() {
    		for(int i=0;i<100;i++)
    			System.out.println(Thread.currentThread().getName()+" "+i);
    	}
    	
    	
    }
    

    (2)继承Runnable接口

       

    public class MyRunnable implements Runnable{
    	
    	private boolean stop=false;
    
    	@Override
    	public void run() {
    		for(int i=0;i<100&&!stop;i++){
    			System.out.println(Thread.currentThread().getName()+" "+i);
    		}
    		
    	}
    	
    	public void stopThread(){
    		this.stop=true;
    	}
    	
    	
    }

      二者的区别在于Thread继承Runnable类,然后再继承Thread类从而调用线程,而Runnable类是一个接口,通过直接继承Runnable类来实现。

    同时二者在创建时还有区别

    测试 Thread:

    public void testThread() {
    		for (int i = 0; i < 100; i++) {
    			System.out.println(Thread.currentThread().getName() + " " + i);
    
    			if (i == 30) {
    				MyThread myThread1 = new MyThread("窗口1");
    				MyThread myThread2 = new MyThread("窗口2");
    				MyThread myThread3 = new MyThread("窗口3");
    				MyThread myThread4 = new MyThread("窗口4");
    				myThread1.start();
    				myThread2.start();
    				myThread3.start();
    				myThread4.start();
    			}
    		}
    
    	}
    

    测试Runnable方式:

    public void testRunnable() {
    		int i = 0;
    		for (i = 0; i <= 100; i++) {
    			System.out.println(Thread.currentThread().getName() + " " + i);
    			if (i == 30) {
    				Runnable myRunnable = new MyRunnable();
    				Thread thread1 = new Thread(myRunnable);
    				Thread thread2 = new Thread(myRunnable);
    				thread1.start();
    				thread2.start();
    			}
    		}
    
    	}
    

    可以看出来在继承Thread类后通过new 一个继承了Thread的MyThread类来实现线程的创建,然后通过调用Thread方法中的start()方法使线程处于就绪状态。

    而继承了Runnable方法的类new一个MyRunnable 然后在将myRunnable放入new的一个Thread中,然后在通过start()方法使线程处于就绪状态。

    3.继承Callable类

    public class MyCallable implements Callable<Integer> {
    
    	private int i=0;
    	@Override
    	public Integer call() throws Exception {
    		int sum=0;
    		for(;i<100;i++){
    			System.out.println(Thread.currentThread().getName()+" "+i);
    			sum+=i;
    		}
    		return sum;
    	}
    
    }

     测试:

    public void testCallable() {
    		Callable<Integer> myCallable = new MyCallable();
    		FutureTask<Integer> ft = new FutureTask<>(myCallable);
    		for (int i = 0; i <= 100; i++) {
    			System.out.println(Thread.currentThread().getName() + " " + i);
    			if (i == 30) {
    				Thread thread = new Thread(ft);
    				thread.start();
    			}
    		}
    		System.out.println("主线程执行完毕");
    		try {
    			int sum = ft.get();
    			System.out.println("sum= " + sum);
    		} catch (Exception e) {
    
    			e.printStackTrace();
    		}
    	}
    

      通过测试你会发现继承了Callable类之后会通过FutureTask类进行包装,然后再在Thread中调用,查api你会看到FutureTask类既继承了Future类又继承了Runnabl类,同时Callabl类与另外两个的区别在于call方法有返回参数。

  • 相关阅读:

    bzoj3052: [wc2013]糖果公园
    莫队算法心得
    bzoj1104: [POI2007]洪水pow
    bzoj1102: [POI2007]山峰和山谷Grz
    bzoj1121: [POI2008]激光发射器SZK
    bzoj1113: [Poi2008]海报PLA
    bzoj1103: [POI2007]大都市meg
    bzoj1396: 识别子串
    bzoj3756: Pty的字符串
  • 原文地址:https://www.cnblogs.com/smallbrokenchildwen/p/7096337.html
Copyright © 2020-2023  润新知