Java多线程

标签 :java基础


1. Java多线程的实现

(1)继承Thread类,重写run方法。
(2)实现Runnable接口,重写run方法。(这个设计比较好)
本质上Thread类就是实现了Runable的类。

// 创建线程
Runnable task = new TaskClass();
// 开启线程
new Thread(task).start();

2. 线程池使用

使用ExecutorService类和Executors类实现线程池,代码如下:

// 固定线程数的线程池
ExecutorService executor = Executors.newFixedThreadPool(3);
// 按需创建新线程的线程池
ExecutorService executor2 = Executors.newCachedThreadPool();
// 使用线程池
executor.execute(new TaskClass());
// 关闭线程池
executor.shutdown();

3. 线程同步问题

(1)竞争状态问题:多个线程以冲突的方式访问一个公共资源
(2)线程安全的类:该类的对象在多线程下没有导致竞争状态问题。
线程安全、不安全的类就是指这种公共资源类

4. 解决线程同步问题

(1)给临界区方法加synchonized关键字。
  一个线程访问这个方法时,整个对象锁住,其他线程访问这个对象的任意方法会阻塞,直到解锁。
(2)给需要同步的语句包上synchronized语句块。
  好处是只需要锁住导致线程不安全的语句,而不是锁住整个方法。

synchronized(obj){
    doSomething();
}

(3)显式使用锁。
  实现了Lock接口的对象是一个锁对象。可以利用锁对象对其他对象显式加锁。例如ReentrantLock类,可以创建具有公平策略的锁,即那个线程先来那个先得。(默认不是公平锁)
  使用方法,在需要实现同步访问的类中,组合一个Lock接口的实例,在临界区前调用lock.lock(),在结束后调用lock.unlock()。如下:

public void add(int a){
    lock.lock();
    try{
        // 临界区
        doSomething();
    }
    catch(InterruptedException e){
    }
    finally{
        lock.unlock();
    }
    // 写try-catch这个习惯比较好,保证锁能释放
}

  ReentrantLock类可以创建condition,比synchronzied关键字更灵活可控。
 

5. 线程间合作

(1)使用Condition接口的实例。Condition接口的实例从Lock对象生成,使用时必须获得该Condition的锁(否则抛出异常)。使用方法是把Condition的实例放在Lock实例的他同一个类底下。

// 创建条件
private static Condition condition = lock.newCondition();
// 阻塞当前线程,直到别人来唤醒
condition.await();
// 唤醒所有阻塞线程
condtition.signalAll();

(2)传统方法,监视器。即使用每个对象本身的wait(),notify(),notifyAll()等方法。

6. 生产者/消费者模型

(1)使用一个lock,两个condition(notEmpty和notFull),每次生产/消费时用lock锁住Buffer。
(2)如果生产时发现容器已满,需要等待notFull条件;
(3)同样,如果消费时发现容器为空,则需要等待notEmpty条件。
(4)每次生产完唤醒等待notEmpty条件的线程,每次消费完唤醒等待notFull条件的线程。

转载于:https://www.cnblogs.com/banyu/p/6690982.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值