(28人评价)
JUC
价格 免费

线程调度

实例

class ThreadPoolDemo implements Runnable{

public void run(){

system.out.println("1");}

}

ThreadPoolDemo tpd = new ThreadPoolDemo

1.创建线程池

ScheduledExecutorService pool = Executors.newScheduledThreadPool(5);

2.为线程池中的线程分配任务

Future<Integer> resule = pool.schedule(new Callable<Integer>(){},3,TimeUnit.SECONDS);

第一个数据意思为传入线程实例,第二个数据为延迟时间,第三个数据为延迟单位

3.关闭线程池

pool.shudown();

[展开全文]

线程池

概念与作用和数据库连接池差不多

 

java.util.concurrent.Executor  负责线程的使用与调度的根接口

子接口:ExecutorSrvice 线程池的主要接口

实现类:ThreadPoolExecutor

子接口:ScheduledExecutorService 负责线程的调度

实现类:ScheduledThreadPoolExecutor         继承了ThreadPoolExecutor,实现了ScheduledExecutorService

 

newFixedThreadPool();创建固定大小的线程池。返回值是ExecutorSrvice

newCachedThreadPool();缓存线程池,线程池的数量不固定,可以根据需求自动更改数量。返回值是ExecutorSrvice

newSingleThreadExecutor();创建单个线程池,线程池中只有一个线程。返回值是ExecutorSrvice

 

newScheduledThreadPool();创建固定大小的线程,可以延迟或定时执行任务。返回值是ScheduledExecutorService

实例测试:17:53

实例:

class ThreadPoolDemo implements Runnable{

public void run(){

system.out.println("1");}

}

ThreadPoolDemo tpd = new ThreadPoolDemo

1.创建线程池

ExecutorService pool = Executors.newFixedThreadPool(5);

2.为线程池中的线程分配任务

pool.submit(tpd);

3.关闭线程池

pool.shudown();

 

 

 

[展开全文]

读写锁ReadWriteLock

由于在对同一个数据的操作中,读操作可以有多个线程同时读并且线程安全,而多个线程同时写操作则不安全。所以读写锁是针对这种的一个锁,可以增加程序的效率。

示例:

ReadWriteLock lock = new ReentrantReadWriteLock();//读写锁实例

lock.readLock.lock();//上读锁

lock.readLock().unlock();//释放读锁

tip:读写锁的释放锁步骤也要放在finally中。

[展开全文]

Condition控制线程通信

在Condition中,与wait,notify和notifyAll方法对应的分别是await,signal,signalAll

Condition实例实质上被绑定到一个锁上,要为特定的Lock实例获得Condition实例,要使用newCondition()方法。

例子:

Lock lock = new ReentrantLock(); //获取一个锁的实例

Condition condition = lock.newCondition(); //获取一个Condition实例并绑定到锁上。

此后当对线程操作时使用  condition.await();

condition.signal();

condition.signalAll();

[展开全文]

解决多线程安全问题的方法

1.同步代码块(隐式锁)

2.同步方法(隐式锁)

3.lock锁 (显式锁)

Lock lock = new ReentrantLock();

上锁:lock.lock();

释放锁:lock.unlock(); 释放锁的代码一定要放到finally中以防上了的锁未被释放。

 

[展开全文]

lock锁

Lock lock = new ReentrantLock();

上锁:lock.lock();

释放锁:lock.unlock(); 释放锁的代码一定要放到finally中以防上了的锁未被释放。

[展开全文]

虚假唤醒:

public class TestProductorAndConsumer {

    public static void main(String[] args) {
        Clerk clerk = new Clerk();
        
        Productor pro = new Productor(clerk);
        Consumer cus = new Consumer(clerk);
        
        new Thread(pro, "生产者 A").start();
        new Thread(cus, "消费者 B").start();
    }
}
//店员
class Clerk {
    private int product = 0;
    //进货
    public synchronized void get(){//循环次数:0
        if(product >= 10){
            System.out.println("产品已满!");
    
            try {
                this.wait();
            } catch (InterruptedException e) {
            }
        }
        System.out.println(Thread.currentThread().getName() + " : " + ++product);
        this.notifyAll();
    }
    //卖货
    public synchronized void sale(){//product = 0; 循环次数:0
        if(product <= 0){
            System.out.println("缺货!");
            try {
                this.wait();
            } catch (InterruptedException e) {
            }
        }
        System.out.println(Thread.currentThread().getName() + " : " + --product);
        this.notifyAll();
    }
}

//生产者
class Productor implements Runnable{
    private Clerk clerk;

    public Productor(Clerk clerk) {
        this.clerk = clerk;
    }
    @Override
    public void run() {
        for (int i = 0; i < 20; i++) 
        {
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
            }
            clerk.get();
        }
    }
}

//消费者
class Consumer implements Runnable{
    private Clerk clerk;

    public Consumer(Clerk clerk) {
        this.clerk = clerk;
    }
    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            clerk.sale();
        }
    }
}

此时运行正常,但是当再添加一个生产者消费者线程时,显示出的商店库存数量出现负数。出现了虚假唤醒。当两个消费者都wait在“缺货”位置,商店再进一次货后,notifyAll方法唤醒了所有线程,此时两个线程交替争夺下一句输出,就出现了负数情况。API中提到了解决方法,即 将进货和卖货的if语句转换为while语句即可。

[展开全文]

synchronized同步锁,被synchronized修饰的方法i意味着加了锁,在同一时间内只能有一个线程对该方法进行访问。

变量本身是存储与主存中,当被某一个线程调用之后,会将该变量的复制放入该线程的缓存中进行处理,处理完成后再对主存中的该变量进行更新;而用volatile修饰之后,等同于线程直接在主存中对该变量进行操作,可以避免可见性问题。但volatile不具备互斥性,不能保证变量的“原子性”(不可分割性)。

[展开全文]

一、i++的三个步骤“读-改-写”

int temp = i;

i = i+1;

i =  temp;

二、原子变量:jdk1.5后java.util.concurrent.atomic包下提供了常用的原子变量:

1.volatile保证内存可见性

2.CAS(Compare-And-Swap)算法保证数据原子性

CAS

CAS算法是硬件对于并发操作共享数据的支持

CAS包含三个操作数:

内存值 V

预估值 A

更新值 B

当且仅当V==A,V==B,否则什么操作都不做

 

[展开全文]

volatile关键字:当多个线程进行操作共享数据时,可以保证内存中的数据是可见的。 (可以当做直接在主存中对数据进行修改)

相较于synchronized是一种较为轻量级的同步策略。

注意:

1.voliatile不具备“互斥性”

2.voliatile不能保证变量的“原子性”

[展开全文]

线程八锁

Thread8MonitorTest{

 

}

class  

[展开全文]

volatile关键字 保证内存可见性

CAS算法 保证数据原子性

 

[展开全文]

volatile关键字, 用来修饰共享数据,当多个线程进行操作共享数据时,可以保证内存中数据的可见性,虽然性能会下降,却要比锁的效率要高

(即可以看做每一次的线程操作都会去访问主存,在主存中进行修改,而不是复制一份到线程中再去修改,这样可以防止一些执行效率较高的线程没有机会去再一次访问可能被修改的主存)

volatile 相较于 synchronized 不具备互斥性,亦不能保证变量的原子性

[展开全文]

一、i++的原子性问题:i++的操作实际上分为三个步骤"读-改-写"

    int i = 10;   i= i++;

 int temp = i;

i = i+1;

i = temp;

 

二、原子变量:jdk1.5后java.util.concurrent.atomic 包下提供了常用的源自变量:

         1.volatile 保证内存可见性

         2.CAS (Compare - And - Swap) 算法保证数据的原子性。CAS算法是硬件对于并发操作共享数据的支持。

     CAS包含了三个操作数:

        内存值 V    预估值 A   更新值 B

        当且仅当  V == A时,V= B,否则,将不做任何操作

[展开全文]
volatile 关键字:当多个线程访问共享变量时。可以保证内存中数据是可见的。
     相较于synchronized是一种较为轻量级的同步策略

volatile与synchronized区别:

1.volatile不具有互斥性。

2.不能保证变量原子性

[展开全文]

线程池:

提供了一个线程队列,队列中保存着所有等待状态的线程。避免了创建与销毁额外开销,提高了响应速度。

线程池的体系结构:

java.util.concurrent.Executor:负责线程的使用与调度的跟接口

ExecutorService:子接口,线程池的主要接口

ThreadPoolExecutor:线程池的实现类

ScheduledExecutorService:子接口:负责线程调度

ScheduledThreadPoolExecutor:

继承 ThreadPoolExecutor,实现ScheduledExecutorService

[展开全文]

线程八锁:

1、两个普通同步方法,两个线程,标准打印

//one,two

2、新增Thread.sleep()给getOne(),

//one,two

3、新增普通方法getThree()

//three,one,two

 

线程八锁的关键:

1、非静态同步方法的锁是this,静态同步方法的锁是 对应的 Class 实例

2、

[展开全文]

生产者与消费者问题                 
 *
 * 1、店员货满时,还会不断的向供货商进货;店员没货时还在不断向顾客卖货 解决:加上 等待环唤醒机制,即 wait(),notifyAll() 方法
 * 2、供货商每次等待0.2s供货,店员的进货量少时: 进货线程最后一次等待,没有别的线程唤醒,线程无法结束 解决:去掉if条件的else
 * 3、当有多个供货商和多个消费者时,会产生虚假唤醒问题;  解决: wait()方法存在虚假唤醒问题,所以要一直使用在循环中 while

[展开全文]

课程特色

视频(15)
下载资料(1)
业界大牛亲自授课
前沿技术实时更新
足不出户学编程
关注尚硅谷微信 一键下载全部视频教程

关注尚硅谷微信

一键下载全部视频教程

©2018课程版权均归谷粒学院所有  京ICP备17055252号