线程相关知识总结

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/mn_is_me/article/details/80811238

线程存在的意义:为了更好地利用CPU

1、程序  指令和数据的集合 

2、进程  进程是在处理机上的一次执行过程  进程包含程序  进程的执行离不开程序  程序就是静态的  变成动态就成进程了

3、线程  一个进程包含一个或者多个线程

4、线程的生命周期:

1)创建(new thread()创建一个线程对象)

2)就绪(调取该对象的start()方法 变成可运行 等待获取CPU的使用)

3)运行(就绪状态的线程获取CPU 执行程序代码 )

4)阻塞 (处于某种原因让出CPU  其中阻塞有三种情况:等待阻塞wait()  同步阻塞 synchronized 其他阻塞sleep()/join() 等待超时会返回就绪状态)

5)死亡(结束生命周期  三种情况:a.正常运行结束;b.线程抛异常;c.直接调用stop()方法 这个方法容易死锁)

5、线程的实现

1) 一种是 继承Thread类  

public class ThreadTest extends Thread{
	private String name;
	
	public  ThreadTest(String name) {
		this.name = name;
	}
	//重写run()方法
	public void run(){
		for(int i=0;i<=10;i++){
			System.err.println(name+"正在运行"+i);
		}
	}
	public static void main(String[] args) {
		ThreadTest th1=new ThreadTest("A");
		ThreadTest th2=new ThreadTest("B");
		//调用start()方法
		th1.start();
		th2.start();
	}
}

2)另一种是  实现Runnable接口

public abstract void run();//接口只偶一个抽象方法
public class ThreadTest implements Runnable{//这个Runnable 只有一个抽象的run()方法 
	private String name;
	
	public  ThreadTest(String name) {
		this.name = name;
	}
	//重写run()方法
	public void run(){
		for(int i=0;i<=10;i++){
			System.err.println(name+"正在运行"+i);
		}
	}
	public static void main(String[] args) {
		ThreadTest t1=new ThreadTest("A");
		Thread th1=new Thread(t1);
		ThreadTest t2=new ThreadTest("B");
		Thread th2=new Thread(t2);
		//调用start()方法
		th1.start();
		th2.start();
	}
}

3)还有一种是实现Callable接口

V call() throws Exception;//有返回值 还能抛异常 并且注意 这里是call()方法 而不是run()方法  因此实现的时候重写的方法是call()
public class ThreadTest implements Callable<Integer>{
	@Override
	public Integer call() throws Exception {
		int s=0;
		for(int i=0;i<=10;i++){
			s+=i;
		}
		return s;
	}
	public static void main(String[] args) {
		ThreadTest  c=new ThreadTest();
		//Callable需要依赖FutureTask包装器 用于接收运算结果  FutureTask是Future接口的实现类 
		//FutureTask实现了RunnableFuture 而RunnableFuture 继承了Runnable 和Future接口
		FutureTask<Integer> f=new FutureTask<Integer>(c);

		Thread t=new Thread(f);
		t.start();
		try {
			System.err.println("阻塞 返回结果:"+f.get()+"====无阻塞 返回true/false:"+f.isDone());
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (ExecutionException e) {
			e.printStackTrace();
		}
	}
}

6、ThreadLocal  

      它其实是Thread的局部变量 为每个使用该变量的线程提供独立的变量副本 这个变量副本只是在该线程内使用  因此每个线程可以独立改变自己的副本 不影响其他副本   

这里面可以借用数据库连接的问题先了解使用ThreadLocal的原因  不过我就不贴代码说明  网上有很多详细说明

ThreadLocal这个接口 有四个方法比较重要 (重点看源代码  这里面就不贴出来了 只是简单的总结下我看到的)

public void set(T value)//设置当前线程局部变量的值

public T get()//获得当前线程的局部变量

 public void remove()//删除当前线程的局部变量

private T setInitialValue() //返回该线程局部变量的初始值  这个方法  只是作用于该ThreadLocal类的get()方法的返回值

public T get() {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null) {
            ThreadLocalMap.Entry e = map.getEntry(this);
            if (e != null) {
                @SuppressWarnings("unchecked")
                T result = (T)e.value;
                return result;
            }
        }
        return setInitialValue();
    }

Thread类中有一个ThreadLocalMap类型的变量threadLocals  ThreadLocalMap是ThreadLocal的一个静态内部类

ThreadLocal.ThreadLocalMap threadLocals = null;//这个是Thread里面关于threadLocals 的源代码

threadLocals 就是这个get() set() 和setInitialValue() 的变量map   下面这个方法是get() set() 和setInitialValue()这些方法里面都具有的主要  还是防止内存溢出  这个内容又要上升一个台阶 后期再讨论

Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);

7、ThreadLocal和线程同步机制

都是为了解决多线程中相同变量访问冲突问题

在同步机制中 通过对象的锁机制保证同一时间只有一个线程访问   这一个线程变量被多个线程共享

8、并发 一次处理很多事  线程模型下的概念

9、并行  同时处理多事情

简单通俗来说就是  并发是  两个人用一个饮水机  并行是  两个人同时用两个饮水机



猜你喜欢

转载自blog.csdn.net/mn_is_me/article/details/80811238