java线程基础

(1)    创建:继承Thread类与实现Runnable接口

(2)    stop()不安全,会解除由线程获取的所有锁定

(3)    suspend()易发生死锁,目标线程会停止,却仍持有在这之前获得的锁定。

不应该使用suspend(),而应在自己的Thread类中置入一个标志,指出线程应该活动还是挂起。若标志指出线程应该挂起,便用wait()命其进入等待状态。若标志指出线程应当恢复,则用一个notify()重新启动线程。

(4)  sleep():正在执行的线程主动让出cpucpu去执行其他线程,在sleep指定的时间过后,cpu才会回到这个线程上继续往下执行,如果当前线程进入了同步锁,sleep方法并不会释放锁,即使当前线程使用sleep方法让出了cpu,但其他被同步锁挡住了的线程也无法得到执行。

sleep是线程类(Thread)的方法,调用sleep不会释放对象锁。

(5)  wait():指在一个已经进入了同步锁的线程内,让自己暂时让出同步锁,以便其他正在等待此锁的线程可以得到同步锁并运行,只有其他线程调用了notify方法,调用wait方法的线程就会解除wait状态和程序可以再次得到锁后继续向下运行。waitObject类的方法,对此对象调用wait方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify方法(或notifyAll)后本线程才进入对象锁定池准备获得对象锁进入运行状态。

(6) 使用线程是如何防止出现大的波峰。
意思是如何防止同时产生大量的线程,方法是使用线程池,线程池具有可以同时提高调度效率和限制资源使用的好处,线程池中的线程达到最大数时,其他线程就会排队等候。

(7) 程序什么时候应该使用线程,什么时候单线程效率高。

耗时的操作使用线程,提高应用程序响应
并行操作时使用线程,如C/S架构的服务器端并发线程响应用户的请求。

多CPU系统中,使用线程提高CPU利用率
改善程序结构。一个既长又复杂的进程可以考虑分为多个线程,成为几个独立或半独立的运行部分,这样的程序会利于理解和修改。
其他情况都使用单线程。

(8) 线程同步,并发操作

在方法名前加关键字syschronized来处理多个线程同时访问共享资源。syschronized相当于一把锁,当有申请者申请该资源时,如果该资源没有被占用,那么将资源交付给这个申请者使用,在此期间,其他申请者只能申请而不能使用该资源,当该资源被使用完成后将释放该资源的锁,其他申请者可申请使用。

并发控制主要是为了多线程操作时带来的资源读写问题。如果不加以空间可能会出现死锁,读脏数据、不可重复读、丢失更新等异常。

并发操作可以通过加锁的方式进行控制,锁又可分为乐观锁和悲观锁。

悲观锁:并发模式假定系统中存在足够多的数据修改操作,以致于任何确定的读操作都可能会受到由个别的用户所制造的数据修改的影响。也就是说悲观锁假定冲突总会发生,通过独占正在被读取的数据来避免冲突。但是独占数据会导致其他进程无法修改该数据,进而产生阻塞,读数据和写数据会相互阻塞。

乐观锁:假定系统的数据修改只会产生非常少的冲突,也就是说任何进程都不大可能修改别的进程正在访问的数据。乐观并发模式下,读数据和写数据之间不会发生冲突,只有写数据与写数据之间会发生冲突。即读数据不会产生阻塞,只有写数据才会产生阻塞。

(9)  线程安全定义:

当多个线程访问一个类时,如果不用考虑这些线程在运行时环境下的调度和交替执行,并且不需要额外的同步及在调用方代码不必做其他的协调,这个类的行为仍然是正确的,那么这个类就被称之为是线程安全的。简言之对于线程安全类的实例进行顺序或并发的一系列操作,都不会导致实例处于无效状态。

只有对象状态可变,且存在对象共享,才需要考虑线程安全。

可以通过下面的方法来确保线程安全:

l 无状态对象:

无状态对象不包含域也没有引用其他类的域,一次特定计算的瞬时状态只会唯一存在本地变量中,这些本地变量存储在线程的栈中,只有执行线程才能访问,因此无状态对象永远是线程安全的。

l 不可变对象:

不可变对象需要满足下面条件:

A.对象本身是final的(避免被子类化),所有域都是final类型。

B.不可变对象的状态在创建后就不能再改变,每次对他们的改变都是产生了新的不可变对象的对象。

C.不可变对象能被正确地创建(在创建过程中没有发生this引用逸出)。

不可变对象是线程安全的,不需要任何同步或锁的机制就可以保证安全地在多线程之间共享。

l 原子变量:

介绍原子变量前首先介绍原子操作,假设有操作A和B,如果从执行A的角度看,当其他线程执行B时,要么全部执行完成,要么一点都没有执行,这样A和B互为原子操作,不满足原子操作要求的操作被称为复合操作,原子操作是线程安全的。

JDK的java.util.concurrent.atomic包中包括了原子变量类,这些类用来实现数字和对象引用的原子状态转换。

原子变量自身是线程安全的,但是如果一个不变约束涉及多个变量时,变量间不是彼此独立的,无论这些变量是否是原子变量都不能确保线程安全,而需要在同一个原子操作中更新这些相互关联的状态变量才能确保线程安全。

l 正确使用线程同步:

通过使用synchronized关键字独占锁、显式锁、volatile等同步机制实现的相对线程安全。

(10) 线程的四种状态

A.新状态:线程已被创建但尚未执行(start() 尚未被调用)。

B.可执行状态:线程可以执行,虽然不一定正在执行。CPU 时间随时可能被分配给该线程,从而使得它执行。

C.死亡状态:正常情况下 run() 返回使得线程死亡。调用 stop()或 destroy() 亦有同样效果,但是不被推荐,前者会产生异常,后者是强制终止,不会释放锁。

D.阻塞状态:线程不会被分配 CPU 时间,无法执行。

(11) 线程的优先级

  线程的优先级代表该线程的重要程度,当有多个线程同时处于可执行状态并等待获得CPU 时间时,线程调度系统根据各个线程的优先级来决定给谁分配 CPU 时间,优先级高的线程有更大的机会获得 CPU 时间,优先级低的线程也不是没有机会,只是机会小一些。

可以调用 Thread 类的方法 getPriority() 和 setPriority()来存取线程的优先级,线程的优先级界于1(MIN_PRIORITY)和10(MAX_PRIORITY)之间,缺省是5(NORM_PRIORITY)

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值