线程

关于线程

线程与进程
进程:真正运行时的应用程序 (程序是静止的),由多个线程组成
     而单核cpu在任何时间点上只能运行一个进程>>>>>宏观并行,微观串行
线程((轻量级进程)Light Weight Process):进程的执行单位,一个程序中的顺序执行流程
多线程:彼此间完成不同的工作,交替执行
并发与并行
并发:多个任务同时请求执行,但cpu只能处理一个,需要cpu轮转执行
多线程的并发原理:cpu分时间片,交替执行,宏观并行,微观串行
并行:多个任务同时请求执行,需要多核cpu的支持
多核cpu:宏观并行,微观并行
线程的基本组成部分(实现原理)
cpu时间片
运行数据:
    堆空间:储存线程需要使用的对象,多个线程可共享堆中对象
    栈空间:储存线程需要使用的局部变量,每个线程都拥有独立的栈
线程的逻辑代码:启动代码和执行代码
线程的实现方式
设置线程的名称:
1.通过构造方法设置线程的名称
2.通过setName方法
3.获取当前线程的对象Thread.currentThread()

继承类(继承Thread类):
实现一个线程类步骤:
	1.自定义一个类 继承 Thread类 
	2.重写run方法
	3.将这个线程要执行的代码写到run方法中
	4.创建自定义类的对象
	5.用自定义类的对象调用start方法开启线程
好处:代码相对简洁
弊端:Java是单继承的 如果一个类有父类就不能通过继承Thread类创建线程类


实现接口(Runnable接口):
Runnable 接口 只有一个run  没有抛出任何的异常  run方法没有返回值
创建线程类的步骤
	1.自定义类 实现 Runnable 接口
	2.实现接口中的run方法
	3.将线程要做的事写在 run方法中
	4.创建自定义类的对象(资源对象)
	5.创建线程Thread t1 =  new Thread(资源对象);
	6.线程对象调用start方法启动线程
好处:Java是单继承的 但是一个类可以同时实现多个接口 不会影响Java的单继承性
弊端:代码稍微繁琐一点

匿名内部类创建线程的方式:
继承一个类 或者 实现一个接口
继承Thread类的匿名内部类实现方式:
语法:Thread 对象名=new Thread(){
    public void run(){//重写run方法
        //线程要执行的代码
    }
};
实现接口的匿名内部类的实现方式
语法:    //创建资源对象
		//创建线程对象
		new Thread(new Runnable(){
			public void run() {//实现run方法
				//线程要执行的代码
			}	
		}).start();

线程池:
Executor 父类
	ExecutorService子类
Executors 工厂类  
	静态的方法  都可以通过类名调用
	newFixedThreadPool(线程的条数)
    newCachedThreadPool() 能够获取动态的线程池 根据任务提交的次数
步骤:
1.创建一个线程池 
ExecutorService eService = Executors.newFixedThreadPool(固定数量);
ExecutorService eService = Executors.newCachedThreadPool();//动态的线程池
2.创建资源对象
3.eService.submit(资源对象);
4.eService.shutdown();


Callable接口
jdk5 提供了 Callable接口 
class 类名 implements Callable<数据类型>{
	public 数据类型 call() throws Exception {
		//线程的代码
	}
	return 结果;
}
Future 对象的引用中存放着异步计算的结果  需要通过get方法区获取异步计算的结果

线程的状态
1. 初始状态(New状态)
2. 就绪状态(Ready状态) 
3. 运行状态(Running状态)
4. 有限期状态(Timed Waiting状态) 
5. 无限期状态(Waiting状态) 
6. 阻塞状态(Blocked状态) 
7. 终止状态(Terminated状态)
方法
sleep(毫秒):当一个正在执行的线程 调用sleep(毫秒数)后线程就进入到一              个限时等待状态 当毫秒数已过  就会重新成为就绪状态 等着抢夺              cpu资源 
插队线程
join():当一个线程调用join方法后 会抢夺当前线程的cpu 等到自己执行完之后         才让出cpu
join(毫秒):当一个线程调用join(毫秒) 在毫秒的范围内 和join一样  一旦            超过了这个时间  就和之前一样 公平的抢夺cpu资源
setDaemon(布尔值): 当方法的参数为true 设置调用该方法的线程为守护线程
                    解释:当某个线程设置为了守护线程,这个线程在其他线                     程执行结束后,不管它的任务有没有执行完,也随着结束
                    
线程安全
临界资源:多个线程共同操作的资源对象 当多个线程对临界资源进行写操作的时候          如果线程不安全会出现数据错误的情况
原子操作:不可分割的一段代码 在线程运行这段代码的时候 不能被其他的线程打断
同步代码块:
synchronized(临界资源对象){
}
同步方法:
语法:
public synchronized 方法的返回值类型   方法名(){}
说明:在同步方法中的代码是一个不可分割的原子操作

jdk5提供一个接口 Lock 接口 
Lock接口下边有 ReentrantLock实现类:
步骤:获得一个锁对象  
	锁对象.lock
	原子操作的代码
	锁对象.unlock
线程通信
sleep(毫秒值):进入到限时等待状态 但是没有释放锁标记

wait():进入到了阻塞状态 释放了锁标记 无限期阻塞  如果这个线程想进入到就绪状态 那么必须由其他的线程去唤醒notifyAll()/notify():在所有的阻塞的线程中唤醒全部/单个线程
这两个方法只能用在加锁的的同步代码块中  只有锁对象可以去调用
关于线程安全的集合
通过集合工具类Collections可以获得安全的集合:
public static <T> List<T> synchronizedList(List<T> list)	
public static <T> Set<T> synchronizedSet(Set<T> s)
public static <K,V> Map<K,V> synchronizedMap(Map<K,V> m)

读写锁:ReadWriteLock,所在包java.util.concurrent.locks
①  概念:一种支持一写多读的同步锁,可分别分配读锁、写锁。
一个集合中 读的操作 查询size  通过get()获得元素  不改变元素的值
写操作 改变了集合中元素的值 (增加元素 插入元素  删除元素)
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值