多线程和线程

Java 创建线程的方式:

      Thread, Runnable , Callable和Future, Executor

线程和进程的区别:

  1. 线程是Cpu最小调度单位,  进程是资源分配最小单位
  2. 一个进程可以有多个线程

wait和sleep的区别:

  1. 两个方法分别来自Thread和Object
  2.  最主要的是sleep方法没有释放锁, 而wait释放了锁, 使得其他线程可以使用同步控制快或者方法.
  3. wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在任何地方使用(使用范围)  
  4. sleep必须捕获异常,而wait,notify和notifyAll不需要捕获异常  
  5. sleep方法属于Thread类中方法,表示让一个线程进入睡眠状态,等待一定的时间之后,自动醒来进入到可运行状态,不会马上进入运行状态,因为线程调度机制恢复线程的运行也需要时间,一个线程对象调用了sleep方法之后,并不会释放他所持有的所有对象锁,所以也就不会影响其他进程对象的运行。但在sleep的过程中过程中有可能被其他对象调用它的interrupt(),产生InterruptedException异常,如果你的程序不捕获这个异常,线程就会异常终止,进入TERMINATED状态,如果你的程序捕获了这个异常,那么程序就会继续执行catch语句块(可能还有finally语句块)以及以后的代码。  
  6. 注意sleep()方法是一个静态方法,也就是说他只对当前对象有效,通过t.sleep()让t对象进入sleep,这样的做法是错误的,它只会是使当前线程被sleep 而不是t线程  
  7.  wait属于Object的成员方法,一旦一个对象调用了wait方法,必须要采用notify()和notifyAll()方法唤醒该进程;如果线程拥有某个或某些对象的同步锁,那么在调用了wait()后,这个线程就会释放它持有的所有同步资源,而不限于这个被调用了wait()方法的对象。wait()方法也同样会在wait的过程中有可能被其他对象调用interrupt()方法而产生  

yield()和join()

  1. yield()方法是停止当前线程,让同等优先权的线程或更高优先级的线程有执行的机会。如果没有的话,那么yield()方法将不会起作用,并且由可执行状态后马上又被执行。   
  2. join方法是用于在某一个线程的执行过程中调用另一个线程执行,等到被调用的线程执行结束后,再继续执行当前线程。如:t.join();//主要用于等待t线程运行结束  

什么导致线程阻塞

  1. Thread.sleep(int millsecond)或者wait(),子线程join()
  2. 线程执行到同步代码且获取不到锁
  3. 线程执行某些IO操作 System.in
  4. 网络请求时的阻塞(Socket)

synchronized和volatile的区别

  1. volatile只能作用于变量,使用范围较小。synchronized可以用在变量、方法、类、同步代码块等,使用范围比较广。 
  2.  volatile只能保证可见性和有序性,不能保证原子性。而可见性、有序性、原子性synchronized都可以保证。 
  3.  volatile不会造成线程阻塞。synchronized可能会造成线程阻塞。

synchronized和reentrantlock的区别(Link)

  1. ReentrantLock功能性方面更全面,比如时间锁等候,可中断锁等候,锁投票等,因此更有扩展性。在多个条件变量和高度竞争锁的地方,用ReentrantLock更合适,ReentrantLock还提供了Condition,对线程的等待和唤醒等操作更加灵活,一个ReentrantLock可以有多个Condition实例,所以更有扩展性。
  2. ReentrantLock必须在finally中释放锁,否则后果很严重,编码角度来说使用synchronized更加简单,不容易遗漏或者出错。
  3. ReentrantLock 的性能比synchronized会好点。
  4. ReentrantLock提供了可轮询的锁请求,他可以尝试的去取得锁,如果取得成功则继续处理,取得不成功,可以等下次运行的时候处理,所以不容易产生死锁,而synchronized则一旦进入锁请求要么成功,要么一直阻塞,所以更容易产生死锁。

死锁产生的必要条件(必须同时满足)

  1. 互斥条件:进程要求对所分配的资源进行排它性控制,即在一段时间内某资源仅为一进程所占用。
  2. 请求和保持条件:当进程因请求资源而阻塞时,对已获得的资源保持不放。
  3. 不剥夺条件:进程已获得的资源在未使用完之前,不能剥夺,只能在使用完时由自己释放。
  4. 环路等待条件:在发生死锁时,必然存在一个进程–资源的环形链。

预防死锁:

  1. 资源一次性分配:一次性分配所有资源,这样就不会再有请求了:(破坏请求条件)
  2. 只要有一个资源得不到分配,也不给这个进程分配其他的资源:(破坏请保持条件)
  3. 可剥夺资源:即当某进程获得了部分资源,但得不到其它资源,则释放已占有的资源(破坏不可剥夺条件)
  4. 资源有序分配法:系统给每类资源赋予一个编号,每一个进程按编号递增的顺序请求资源,释放则相反(破坏环路等待条件) 

避免死锁:

预防死锁的几种策略,会严重地损害系统性能。因此在避免死锁时,要施加较弱的限制,从而获得 较满意的系统性能。由于在避免死锁的策略中,允许进程动态地申请资源。因而,系统在进行资源分配之前预先计算资源分配的安全性。若此次分配不会导致系统进入不安全的状态,则将资源分配给进程;否则,进程等待。其中最具有代表性的避免死锁算法是银行家算法。

银行家算法:首先需要定义状态和安全状态的概念。系统的状态是当前给进程分配的资源情况。因此,状态包含两个向量Resource(系统中每种资源的总量)和Available(未分配给进程的每种资源的总量)及两个矩阵Claim(表示进程对资源的需求)和Allocation(表示当前分配给进程的资源)。安全状态是指至少有一个资源分配序列不会导致死锁。当进程请求一组资源时,假设同意该请求,从而改变了系统的状态,然后确定其结果是否还处于安全状态。如果是,同意这个请求;如果不是,阻塞该进程知道同意该请求后系统状态仍然是安全的。

检测死锁:

首先为每个进程和每个资源指定一个唯一的号码;

然后建立资源分配表和进程等待表。 

解除死锁:

  1. 剥夺资源:从其它进程剥夺足够数量的资源给死锁进程,以解除死锁状态;
  2. 撤消进程:可以直接撤消死锁进程或撤消代价最小的进程,直至有足够的资源可用,死锁状态.消除为止;所谓代价是指优先级、运行代价、进程的重要性和价值等。
死锁例子
class ThreadLock {

    constructor()

    companion object{
        val obj1 = "obj1"
        val obj2 = "obj2"
    }

    fun test(){
        Thread(Lock1()).start()
        Thread(Lock2()).start()
    }

    class Lock1 : Runnable {
        override fun run() {
            println("lock 1 is running")
            while (true){
                synchronized(obj1){
                    println("lock1 lock obj1")
                    sleep(2000)// 睡眠让lock2 有足够的时间锁住obj2
                    synchronized(obj2){
                        println("lock1 lock obj2")
                    }
                }
            }
        }
    }

    class Lock2: Runnable{
        override fun run() {
            println("lock2 is running")
            while (true){
                synchronized(obj2){
                    println("lock2 lock obj2")
                    sleep(2000)
                    synchronized(obj1){
                        println("lock2 lock obj1")
                    }
                }
            }
        }
    }

}

断点续传

    重要类RandomAccessFile

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值