标签:影响 this 无法 rgs 内部类 maximum 调用 pool 静态
Java.Thread
一个进程-->多个线程
进程:执行程序的一次执行过程
线程:就是独立的执行路径
现在的多线程 多是 模拟出来的
三种创建方式:
继承Thread(重点)
自定义线程类继承Thread类
重写run()方法,编写线程执行体
创建线程对象,调用start()方法启动线程
实现Runnable接口(重点)
定义MyRunnable类实现Runnable接口
实现run()方法,编写线程执行体
创建线程对象,调用start()方法启动线程
实现Callable接口(了解 )
实现Callable接口,需要返回值类型
重写call方法,需要抛出异常
创建目标对象
创建执行服务:ExecutorService ser + Executors.newFixedThreadPool(1);
提交Future<Boolean> result1 = ser.submit(t1);
获取结果: boolean r1 = result1.get()
关闭服务:ser.shutdownNow();
为什么要使用Lambda表达式 :
避免匿名内部类定义过多
可以让你的代码看起来很简洁
去掉了一堆没有意义的代码,只留下核心的逻辑.
任何接口,如果只包含唯一一个抽象方法,那么它就是一个函数式接口.
对于函数式接口,我们可以通过lambda表达式来创建该接口的对象.
推导lambda表达式:
/*
推导lambda表达式 最初代码
*/
public class TestLambda1 {
public static void main(String[] args) {
ILike like = new Like();
like.lambda();
}
}
//1.定义一个函数式接口
interface ILike{
void lambda();
}
//2.实现类
class Like implements ILike{
public void lambda() {
System.out.println("i like lambda");
}
}
/*
推导lambda表达式 2.3.4.5.6是各种实现接口的方法,逐层推进
idea若是报错:将ProjectSettings 中Language level改成 8
参考:https://blog.csdn.net/fenghuibian/article/details/52704057
*/
public class TestLambda1 {
//3.静态内部类
static class Like2 implements ILike{
public void lambda() {
System.out.println("i like lambda2");
}
}
public static void main(String[] args) {
ILike like = new Like();
like.lambda();
like = new Like2();
like.lambda();
//4.局部内部类
class Like3 implements ILike{
public void lambda() {
System.out.println("i like lambda3");
}
}
like = new Like3();
like.lambda();
//5.匿名内部类,没有类的名称,必须借助接口或父类
like = new ILike() {
public void lambda() {
System.out.println("i like lambda4");
}
};
like.lambda();
//6.用lambda简化
like = ()->{
System.out.println("i like lambda5");
};
like.lambda();
}
}
//1.定义一个函数式接口
interface ILike{
void lambda();
}
//2.实现类
class Like implements ILike{
public void lambda() {
System.out.println("i like lambda");
}
}
总结:
线程常用方法
创建-->就绪状态-->(阻塞状态)-->运行状态-->dead
setPriority(int newPriority) : 更改线程的优先级
static void sleep(long millis) : 在指定的毫秒内让当前正在执行的线程休眠
void join() : 等待该线程终止
static void yield() : 暂停当前正在执行的线程对象,并执行其他线程
void interrupt() : 中断线程,别用这个方式
boolean isAlive() : 测试线程是否处于活动状态
死亡后的线程不能再次启动
测试线程优先级:setPriority(int); int型:1~10
守护(daemon)线程:thread.setDaemon(true)
由于同一进程的多个线程共享一块存储空间,在带来方便的同时,也带来了访问冲突问题,为了保证数据在方法中被访问时的正确性,在访问时加入锁机制 synchronized,当一个线程获得对象的排它锁,独占资源,其他线程必须等待,使用后释放锁即可,存在以下问题:
死锁
线程A拥有线程B的资源,现在需要线程B的资源,但线程B此时也再等A的资源,两个线程都无法向下运行,造成死锁。
产生死锁的四个必要条件
通过Lock(锁)类实现锁
synchronized与Lock的对比:
Lock是显示锁(手动开启,手动关闭),synchronized是隐式锁,出了作用域自动释放
Lock只有代码块锁,synchronized有代码块锁和方法锁
使用Lock锁,JVM将花费较少的时间来调度线程,性能更好。并且具有更好的扩展性(提供更多的子类)
优先使用顺序:
Producer(生产者)--> 数据缓冲区 --> Consumer(消费者)
package gaoji;
//测试:生产者消费者模型-->利用缓冲区解决:管程法
//生产者,消费者,产品,缓冲区
public class TestPC {
public static void main(String[] args) {
SynContainer container = new SynContainer();
new Productor(container).start();
new Consumer(container).start();
}
}
//生产者
class Productor extends Thread{
SynContainer container;
public Productor(SynContainer container){
this.container = container;
}
//成产
@Override
public void run(){
for (int i = 0; i < 100; i++) {
container.push(new Chicken(i));
System.out.println("生产了"+i+"只鸡");
}
}
}
//消费者
class Consumer extends Thread{
SynContainer container;
public Consumer(SynContainer container){
this.container = container;
}
//消费
@Override
public void run(){
for (int i = 0; i < 100; i++) {
System.out.println("消费了--》"+container.pop().id+"只鸡");
}
}
}
//产品
class Chicken{
int id;//产品编号
public Chicken(int id) {
this.id = id;
}
}
//缓冲区
class SynContainer{
//需要一个容器大小
Chicken[] chickens = new Chicken[10];
//容器计数器
int count = 0;
//生产者放入产品
public synchronized void push(Chicken chicken){
//如果容器满了,就需要等待消费者
if(count == chickens.length){
//通知消费者消费,生产等待
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//如果没有满,我们就需要丢入产品
chickens[count] = chicken;
count++;
//可以通知消费者了
this.notifyAll();
}
//消费者消费产品
public synchronized Chicken pop(){
//判断是否能消费
if(count==0){
//等待生产者生产,消费者等待
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//如果可以消费
count--;
Chicken chicken = chickens[count];
//吃完了,通知生产者生产
this.notifyAll();
return chicken;
}
}
线程池:
背景:经常创建和销毁、使用量特别大的资源,比如并发情况下的线程,对性能影响很大。
思路:提前创建好多个线程,放入线程池中,使用时直接获取,使用完放回池中。可以避免频繁的创建和销毁,实现重复利用。类似生活中的公共交通工具。
好处:
提高响应速度(减少了创建新线程的时间)
降低资源消耗(重复利用线程池中的线程,不需要每次都创建)
便于线程管理(....)
ExecutorService:真正的线程池接口。常见子类 ThreadPoolExecutor
Executors:工具类、线程池的工厂类,用于创建并返回不同类型的线程池。
标签:影响 this 无法 rgs 内部类 maximum 调用 pool 静态
原文地址:https://www.cnblogs.com/fzly-88/p/12376007.html