聊一聊线程

线程是依赖于进程的,一个进程可以有一个或多个线程。我们创建线程的方式有四种。

1、通过继承Thead来创建线程,重写run方法。
2、实现Runnable接口创建线程类,因为我们Runnable接口没有start()方法,必须要先挂载到某一个线程上才可以执行。
3、实现Callable接口创建线程类,它是要重写call()方法的,这个类无法启动线程,它是必须先创建子类的实例,再创建FutureTask实例并挂载,最后创建线程实例,将创建FutureTask实例对象挂载到线程中。
4、线程池的使用。线程池可以一次性创建线程而且还可以重用。

线程的生命周期是什么?线程有它的生命周期,它的生命周期有两种方式体现。

第一种就是先创建一个线程的实例后调用start()方法进入就绪状态,通过CPU资源的调度进入运行状态,然后销毁。

第二种就是在运行当中因为某种原因,比如休眠导致阻塞,我们就可以先创建一个线程的实例后调用start()方法进入就绪状态,通过CPU资源的调度进入运行状态,进入阻塞状态,解除阻塞后进入就绪状态,然后通过CPU资源的调度进入运行状态,然后销毁。

线程允许休眠,以毫秒为单位,如果休眠了,线程会在休眠时间到达以后自动唤醒。我们线程允许优先级默认优先级NORM_PRIORITY为5,最大优先级MAX_PRIORITY为10,最小优先级MIN_PRIORITY为1,我们可以通过方法来改变它的优先级,因为线程是争抢CPU控制权的。

假如你的线程设定了优先级,线程不一定优先运行,只是机率增大了。既然我们现在有多种创建方式,那使用哪一种比较好呢?

推荐使用interface接口或线程池,因为我们JAVA是个单继承,如果使用继承Thead,就会导致只能单一继承,使用方法减少。Runnable中的run方法与Callable的call方法差别很大,call方法是有返回值类型,能够抛出异常。

线程池可以销毁线程,而单个线程就必须手动关闭。线程中有一个问题必须引起高度重视,那就是线程安全问题。线程安全就是多个线程使用同一个资源,这样操作的后果就是带来数据不一致。

在线程中提供了两个方法来解决这个问题,synchronized和lock
我们集合有线程安全和线程不安全的,比如HasnMap和HashTable,Vector和ArrayList。

如果你想用线程安全的集合推荐使用vector,如果想让ArrayList线程安全的话可以使用List list = Collections.synchronizedList(new ArrayList(…));

那为什么Verctor和HashTable就是安全的呢,我们在检查它们的Add方法和Remove方法的时候,发现它使用了synchronized关键字进行保护,后果就是效率比较低,现在有一种集合它兼顾了安全和效率。

它就是ConcurrentHashMap,Sping的IOC(控制反转)就是采用这个集合。当我创建一个固定长度的线程时,我将它的长度改成负数,会报一个非法参数异常。

线程同步发生在多个线程操作共享资源时 使用synchronized可以锁定操作资源。若有多个线程同时执行写操作,一般都需要考虑线程同步,否则的话就可能影响线程安全。

锁是控制多个线程对共享资源进行访问的工具。通常,锁提供了对共享资源的独占访问。

一次只能有一个线程获得锁,对共享资源的所有访问都需要首先获得锁。

1、Lock是java的一个interface接口,而synchronized是Java中的关键字,
synchronized是由JDK实现的,不需要程序员编写代码去控制加锁和释放;

2、synchronized修饰的代码在执行异常时,jdk会自动释放线程占有的锁,
不需要程序员去控制释放锁,因此不会导致死锁现象发生;
但是,当Lock发生异常时,如果程序没有通过unLock()去释放锁,
则很可能造成死锁现象,因此Lock一般都是在finally块中释放锁;

3、Lock可以让等待锁的线程响应中断处理,如tryLock(long time, TimeUnit unit),而synchronized却不行,使用synchronized时,等待的线程会一直等待下去,不能够中断,程序员无法控制;

4、 synchronized是非公平锁,Lock可以设置是否公平锁,默认是非公平锁;

5、Lock的实现类ReentrantReadWriteLock提供了readLock()和writeLock()
用来获取读锁和写锁的两个方法,这样多个线程可以进行同时读操作;

6、Lock锁的范围有局限性,仅适用于代码块范围,而synchronized可以锁住代码块、对象实例、类;

7、Lock可以绑定条件,实现分组唤醒需要的线程;synchronized要么随机唤醒一个,要么唤醒全部线程。

我们的线程有时候会出现死锁的状态,那么什么时候会出现呢?可参考链接
当线程锁定一个对象之后还要锁定其它对象
但是其它对象在你锁定之前已经被其它线程锁定
于是,造成了无限制的等待。双方互不相让
程序处于僵持状态
解决的办法:
第一:不要锁定太多的对象
第二:不在嵌套锁

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值