java 线程-生命周期-锁-阻塞-生成消费模式-安全容器

线程
1、实现方式
2、生命周期
3、控制线程
4、线程同步三种方式
5、死锁
6、线程通信
7、线程组
8、自定义线程处理类
9、ThreadLocal<T>
10、线程不安全集合的包装与线程安全的集合


1、线程实现的三种方式:
方式1:覆写Thread的run方法
new Thread(){
            @Override
            public void run() {
                
            }
        }.start();


方式2:将Runnbale对象作为Thread的target


new Thread(new Runnable() {
            @Override
            public void run() {
        
            }
        }).start();

查看Thread源码,发现target,在构造方法中被赋值,在run方法中调用target的run方法。
Runnable target;
public void run() {
        if (target != null) {
            target.run();
}
        }

方式3:使用FutureTask,它实现Runnable接口和Callable<V>接口,所以可以作为Thread的target,当run方法执行的时候,调用Callable的call方法,
FutureTask这样就封装了一个有返回值的线程任务,并且封装了public boolean cancel(boolean mayInterruptIfRunning)方法

   FutureTask<String> futureTask = new FutureTask<String>(new Callable<String>() {
            @Override
            public String call() throws Exception {
                return "futureTask";
            }
        });
        new Thread(futureTask).start();

FutureTask是Runnable的实现类,封装一个有返回值有cancel方法的类。这样在线程中调用call方法之后就可以有返回值了。

2、线程生命周期


线程对象new->进入新建状态--如果调用start方法->就绪准备状态--如果被CPU调度执行->运行状态--之后可能进入阻塞状态
再进入就绪状态,也可能直接返回就绪状态,或者进入死亡状态。

a、进入阻塞状态的情况
》调用sleep方法,主动放弃所占有的资源。
》调用了一个阻塞式的IO方法,在方法返回之前,自己被阻塞
》试图获取一个同步锁的时候,等待别的线程释放锁,处于阻塞状态
》调用了wait方法,等待被唤醒期间处于阻塞状态
》调用了线程的suspend方法,该方法容易造成死锁,尽量勿用。
b、阻塞结束,再次进入就绪状态的情况
》sleep的时间结束
》IO方法返回
》拿到锁
》调用wait的对象调用了notify方法
》调用线程的resume方法

3、线程控制的五个方法
   3.1、join():如果线程A在执行的时候,调用了线程B的join,那么线程A将等待线程B执行完之后,自己才会继续往下执行。
        join(long millis),等待线程B执行的最大时间,如果超过这个时间线程B还没有执行完,就不再等待。

   3.2、后台线程setDaemon
        在a线程中,创建一个线程b 
在线程a调用start方法之前,调用setDaemon(true),将a线程设置成为b的后台线程
        当b线程死亡的时候,a线程会跟随b一起死亡。


   3.3、sleep(long millis) 线程睡眠一段时间,如果它拥有锁,它sleep期间是不会释放锁的。
   
   3.4、yield线程让步,让优先级比自己高的线程先执行
   
   3.5、setPriority,设置线程的优先级
   
4、线程同步
   4.1、锁方法,默认是锁住this对象,其它线程不能再同时锁住this对象
   public synchronized void aa(){
        
    }
//锁static方法,锁的是class对象
public static synchronized void aa(){


    }
   4.2、锁指定对象
    public String test = "locked";
    public void testLock(){
        synchronized (test){
            
        }
    }

   4.3、Lock对象,显示的调用 lock(),unlock()进行加锁和释放锁
   
5、死锁:当对象a的 a1方法加了锁,对象b的b1方法也加了锁
         当线程t1和线程t2都可以访问对象a和b
当t1调用a对象的a1方法拿到锁,并且a1方法没有执行完,也就是没有释放a的锁,
这个时候由于某某原因线程t2抢到cpu资源,执行b对象的b1方法,拿到b对象的锁
在b1方法中调用a对象的a1方法,由于这个时候t1并没有释放锁,所以t2进入等待
在t2等待a对象锁的时候,t1抢占到cpu资源继续执行a1方法,这个时候a1方法去访问b对象的b1方法,
由于b对象的锁t2线程还没有释放,所以t1进入阻塞,等待b的锁
于是t1与t2进入死锁。
 
6、线程通信两种方式
    6.1:synchronized来锁一个对象a,可以调用a对象的三个方法与其他线程通信
    wait方法,当被锁的对象调用wait方法之后,当前线程会释放掉对象的锁,并且进入阻塞状态,等待被锁的该
notify方法,随机唤醒调用过a对象的wait方法而进入阻塞状态的一个线程
notifyAll方法,全部唤醒调用过a对象的wait方法而进入阻塞状态的线程
 
6.2 由于还可以使用lock对象来显示的作为一把锁,所以就使用Condition来显示的释放锁和唤醒其他等待线程

private Lock lock  = new ReentrntLock();
private Condition condtiton = lock.newCondition();

通过lock对象来获得condtiton
condtiton.await()==wait一样的作用
condtiton.signal()==notify一样的作用
condtiton.signalAll()==notifyAll一样的作用

在生产与消费模式的时候,如果使用一个普通的list对象作为容器,当生产者先锁住list,然后再放入之前,发现list已经满了,调用list的wait,释放锁
并且调用notifyAll,来唤醒消费者线程进行消费,当消费者消费时候发现list如果是满的,就有可能有生成线程已经处于阻塞所以消费完之后,调用一下notify通知生成者
现在list已经有空余,可以生成了。
。当消费者线程发现list为空的时候,同样调用wait进入,阻塞,调用notifyAll,唤醒生产者进行生成。生产者生成完发现list为1,可能有消费者线程在等待,所以也notify一下。

java提供阻塞队列:
BlockQueue:
失败之后   抛出异常          返回false     阻塞线程

添加        add                offer         put
          
删除       remove              poll          take

获取元素   element             peek           无


7、线程组  ThreadGroup
   ThreadGroup(String name)
   线程得到所在线程组Thread.currentThread().getThreadGroup();
   线程默认属于创建他的线程组
   
   线程组ThreadGroup调用,interrupt中断组中所有线程,setDaemon设置整个线程组为后台线程。。。。
   
   
8、自定义线程处理类


   Thread.currentThread().setUncaughtExceptionHandler(aa)当该线程异常时候,会回调这里,但是并不是tray catch的效果,程序只是
   回调一下而已,还是会和正常的崩溃一样。
   
9、ThreadLocal<T>
   
   ThreadLocal<Object> a = new ThreadLocal()把任意object对象封装成一个数据隔离的对象,每个线程访问a对象的时候,
   都会复制一份a的值到自己的线程中,也就是各个线程都会自己拥有一个单独的a对象,互相不影响。
   
10、将集合封装成线程安全的
    Collection提供的synchronized开头的方法。



               
  

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值