线程不一定执行 由cpu调度安排
(相关资料图)
new THread(new MyThread()).start();
1.实现Callable接口,需要返回值类型2.重写call方法,需要抛出异常3.创建目标对象4.创建执行服务: ExecutorService ser = Executors.newFixedThreadPool(1);5.提交执行: Futureresult1 = ser. submit(t1);6.获取结果: boolean r1 = result1.get()7.关闭服务: ser.shutdownNow();
public interface Runnable(){ punlic abstract void run();}对于函数式接口,我们可以通过lambda表达式来创建接口的对象
new Thread(()->sout("hhhhhhh")).start();
100ms==1s
sleep (时间)指定当前线程阻塞的毫秒数;sleep存在异常 InterruptedException;sleep时间达到后线程进入就绪状态;sleep可以模拟网络延时,倒计时等每一个对象都有一个锁,sleep不会释放锁;让当前正在执行的线程暂停,但不阻塞
让线程从运行状态转为就绪状态
让cpu重新调度,礼让不一定成功! 看cpu心情
join合并线程,代词线程执行完成后 在执行其他线程,其他线程阻塞
可以想象成插队
用数字表示 范围从1~10.
Thread.MIN_PRIORITY=1;Thread.MAX_PRIORITY=10;Thread.NORM_PRIORITY=5;//改变或者获取优先级getPriority().setPriority(int xxx)
线程分为:用户线程 和 守护线程
虚拟机必须确保用户线程执行完毕
虚拟机不用等待守护线程执行完毕
线程同步其实就是一个等待机制
默认的ArryList 线程不安全CopyOnWriteArryLIst 线程安全
锁机制
synchronized 默认锁的是run
synchronized(锁的对象){ //代码块}//锁的对象:需要增删改的对象
都在等待对方的资源
解决方法:不要抱对方的锁 ,从代码块中拿出来
1.互斥条件:一个资源每次只能被一一个进程使用。2.请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。3.不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。4.循环等待条件:若干进程之间形成- -种头尾相接的循环等待资源关系。
class A{ private finall ReenTrantLock lock = new ReenTrantLock(); public void m(){ lock.lock(); try{ //保证线程安全的代码 }finally{ lock.unlock(); //如果同步代码有异常,要将unlock()写入finally语句块 } }}
◆从JDK 5.0开始,Java提供了更强大的线程同步机制一通过 显式定义同步锁对象来实现同步。同步锁使用Lock对象充当◆java.util.concurrent.locks.Lock接口是控制多个线程对共享 资源进行访问的工具。锁提供了对共享资源的独占访问,每次只能有一-个线程对Lock对象加锁,线程开始访问共享资源之前应先获得L ock对象◆ReentrantLock(可重入锁)类实现了Lock,它拥有与synchronized相同的并发性和内存语义,在实现线程安全的控制中,比较常用的是ReentrantLock,可以显式加锁、释放锁。
◆Lock是显式锁(手动开启和关闭锁,别忘记关闭锁) synchronized是隐式锁,出了作用域自动释放◆Lock只有代码块锁,synchronized有 代码块锁和方法锁◆使用Lock锁,JVM将花费较少的时间来调度线程,性能更好。并且具有更好的扩展性(提供更多的子类)◆优先使用顺序:◆Lock >同步代码块(已经进入了方法体,分配了相应资源) >同步方法(在方法体之外)
生产者消费者模式 问题
应用场景:生产者和消费者问题◆假设仓库中只能存放一件产品,生产者将生产出来的产品放入仓库,消费者将仓库中产品取走消费◆如果仓库中没有产品,则生产者将产品放入仓库,否则停止生产并等待,直到仓库中的产品被消费者取走为止.◆如果仓库中放有产品,则消费者可以将产品取走消费,否则停止消费并等待,直到仓库中再次放入产品为止.