Java多线程编程

Java多线程编程,第1张

Java多线程编程 三种实现方式

.run();与.start();,前者在调用时候中断当下执行进程开始执行run方法内容,后者则是创建新的线程并发执行;

继承Thread类与执行Runnable接口区别在于后者需要将线程对象丢进Thread代理类里面进行start,前者的线程对象直接就可以start;通常情况下用执行接口会优于继承,原因是Java单继承的局限性,执行接口可以使同一个线程对象被多次“丢”进Thread对象从而被多次使用;

!new Thread(thread,"name"); 第二个参数可以命名调用执行线程!!

关于Callable接口,可以只抛出异常,需要创建执行服务ExecutorService对象形成线程容器;

之后ExecutorService对象.submit(线程对象);提交给Future(是个啥?)执行,再用boolean变量接受future.get()返回结果,最后用shutdownNow()关闭服务; 

Lambda表达式(Java8)

函数式接口:接口内只有唯一一个抽象方法,才可以用Lambda实现;

 !!实现类的几种形式:(接口回调:接口类型的变量接受不同实现类的对象)(下文实现类为声明的接口变量!!!)

1. 正常实现:定义接口,然后类实现接口重写方法,在测试类的main里面把实现类对象赋给接口变量;

2. 静态内部类:把实现接口的类放到测试类里面用static修饰;

3. 局部内部类:把实现接口的类放到测试类里面的main方法里;

4. 匿名内部类:实现类 = new Interface(){在其中重写函数};

5. Lambda方式 :实现类 = (参数列表)->{ 方法重写 }; (参数列表的括号(仅限单个变量)和变量类型可以去掉。。。方法重写的{}也可以去掉(需要只有一行执行语句)。。。)于是就成了  ↓

     实现类 = 变量 -> 一行执行语句;

静态代理(Java实现Thread的基础)

存在两种实现类皆实现统一接口的指定功能,单一执行的实现类为目标类,而代理类则有collaboration关系,在目标类原有功能基础上进行扩充升级。在Thread类里,Runnable接口变量被丢进Thread的构造方法里就是典型的被Thread类执行代理线程创建。

线程间的状态和方法
  • 线程停止:不建议使用JDK内嵌的停止函数(stop,destroy等),建议使用控制语句逻辑停止; 
  • 关于sleep()方法,需要InterruptedException异常声明,调用后线程变为就绪状态,还可以用来模拟时延,延长线程 *** 作间隙,发现问题。在函数内可以直接调用Thread.sleep()让主线程(mian)休眠。。
  • 关于yield();方法,在多线程被选择调度时,会非阻塞式地等待让CPU重新调度;
  • 关于join();方法,调用时会抢占当前线程直至插队线程执行完。
  • 关于Thread.State变量, 通过getThread()方法返回当前线程状态(Running,Waiting,New,Terminated。。)
  • 线程优先级(main线程休闲级为默认5)(其实是与JVM的协调):getPriority(); setPriority(int num);(在与系统调度冲突的时候会退让,因此有概率性能倒置,yield也是)
  • 守护线程(daemon,如gc,后台日志等)(相对应于用户线程,如main),一般情况下的线程都是默认setDaemon(false);即用户线程,只有单独setDaemon(true);的才被设置为守护线程;JVM不需要等守护线程的结束即可停止。

线程同步(队列+锁) 

不安全案例:不同线程并行 *** 作修改有限资源,线程进行次序的不协调导致资源数目与预期不同;

解决方法:synchronized修饰方法,独占调用该方法的对象锁并使其他企图调用该方法的对象阻塞;由于部分不会造成线程不安全的代码也会被锁住影响效率,synchronized亦可以锁住代码块:synchronized(要锁住的任意会被改变的公共资源(对象集合变量)){修改 *** 作};

死锁产生:synchronized嵌套两个以上的对象资源,加之两个以上的对象占用访问,遂产生,把嵌套结构拆了就可以。

Lock锁(JDK5.0)

显示地用Lock对象定义同步锁,用ReentrantLock(可重入锁)实现Lock接口; 通过ReentrantLock对象的lock与unlock方法的调用进行加锁与解锁,一般在try块里加锁,在finally块里解锁。性能优于synchronized因为JVM对调度的开销变小了;

  

wait()和notify()

wait()会令线程等待且不会释放锁,参数可以设置为等待时长;notifyAll()解除线程等待;

对于特定资源的多线程 *** 作(生产消费),可通过设置缓冲区(保证资源在不同状态下有对不同线程的等待与唤醒,进而保证资源所有状态均能让各线程正常进行)或者信号量(多线程共享对此信号量的修改权限,同时也参考此信号量进行start或者wait)进行多线程同步协调;

线程池

利用Executor对象创建线程池(用ExecutorService接口存储),利用execute方法实现Runnable接口的线程开始,shutDown()关闭连接;

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5695480.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存