首页 > 编程语言 > 详细

多线程

时间:2020-11-15 23:04:12      阅读:32      评论:0      收藏:0      [点我收藏+]

多线程

一、普通方法和多线程

技术分享图片

二、进程和线程

进程(process):运行的程序

线程(thread):是操作系统能够进行运算调度的最小单位

两者关系:

  • 一个进程可以包含多个线程,

  • 进程包含main线程,gc线程。(mian线程是程序的入口,用于执行整个程序)

三、线程的三种创建方式

  1. Thread 类(单继承有局限性)

    //1.继承Thread类
    public class Testthread1 extends Thread{
        @Override
        public void run() {
            //2.重写run方法
            for (int i = 0; i < 20; i++) {
                System.out.println("run"+i);
            }
        }
    
        public static void main(String[] args) {
            //3.创建一个线程对象
            Testthread1 t1 = new Testthread1();
            
            //4.调用start()方法
            t1.start();
            
            for (int i = 0; i < 20; i++) {
                System.out.println("main"+i);
            }
        }
    }
    
  2. Runnable接口(推荐使用)

    //1.实现Runnable接口
    public class Testthread2 implements Runnable{
        @Override
        public void run() {
            //2.重写run方法
            for (int i = 0; i < 20; i++) {
                System.out.println("run"+i);
            }
        }
    
        public static void main(String[] args) {
            //3.创建一个线程对象
            Testthread2 t1 = new Testthread2();
            
            //4.丢入Runnable接口实现类并调用start()方法
            new Thread(t1).start();
           
            for (int i = 0; i < 20; i++) {
                System.out.println("main"+i);
            }
        }
    }
    
  3. Callable接口(了解)

    • 创建执行服务
    • 提交执行
    • 获取结果
    • 关闭服务

注意:线程开启后不一定立即执行,什么时候开启由cpu决定。

四、静态代理

  • 真是对象和代理对象都要实现同一个接口
  • 代理对象要代理真实角色

好处:

  • 代理对象可以做很多真实对象做不了的事情
  • 真实对象专注做自己的事情
new Company(new You()).Wedding();
new Thread(()-> System.out.println("开心")).start();

五、Lamda表达式

public class Lambda {
    public static void main(String[] args) {
        Lmd lmd = () -> {
            System.out.println("I love you.");
        };
        lmd.Like();
    }
}

interface Lmd{
    public void Like();
}

使用Lamda的好处

  • 避免匿名内部类定义过多
  • 可以让代码更加简介
  • 去掉一堆没有意义的代码,只留下核心逻辑

函数式接口:一个接口只包含唯一一个抽象方法。

用Lamda表达式来实现函数式接口。

总结:

  • lambda表达式只能在有一行代码的情况下才能简化成为一行,如果有多行,那么就用代码块包裹
  • 前提是接口为函数式接口
  • 多个参数也可以去掉参数类型,要去掉就都去掉,必须加上括号

六、线程的五大状态

技术分享图片

? 观测线程状态:

thread.getState();
  1. 创建状态 NEW

    Thread t = new Thread();
    
  2. 就绪状态

    t.start();//执行完立即进入就绪状态
    
  3. 运行状态 RUNNABLE

    cpu调度后,开始真正执行线程体的代码块
    
  4. 阻塞状态 BLOCKED

    sleep、wait、或者同步锁
    
  5. 死亡状态 TERMINATED

    线程中断或者结束
    

线程停止:

//设立标志位,利用标志位使线程停止
private Boolean flag = true;
    
public void stop(){
    this.flag = false;
}

public void run() {
    int i = 0;
    while(flag) {
        //content        
    }
}

线程休眠(sleep):

//模拟网络延时
//倒计时
try {
	Thread.sleep(1000); 
} catch (InterruptedException e) {
    e.printStackTrace();
}
Date startT = new Date(System.currentTimeMillis());//获取系统当前时间
System.out.println(new SimpleDateFormat("HH:mm:ss").format(startT));//输出当前系统时间

线程礼让(yield):

//让当前正在执行的线程暂停,但不阻塞
//将线程从运行状态转为就绪状态
//让cpu重新调度,礼让不一定成功,看cpu心情

Thread.yield();

线程强制执行(join):

//Join合并线程,待此线程执行完成后,再执行其他线程
for (int i = 0; i < 200; i++) {
	if (i == 100){
		thread.join();//i=100时,thread会霸占资源,等thread执行完了才会让出资源					   			 	  //从而继续执行主线程
	}
	System.out.println("main"+i);
}

线程优先级(priority):

//优先级默认 1-10
//优先级高不一定就先执行,但其被执行的概率很高

Thread.setPriority(6); //设置优先级
Thread.currentThread().getPriority(); //获取优先级

守护线程(daemon):

//守护线程等用户线程结束后会自动结束
//设置守护线程
Thread.setDaemon(true);  //默认是false表示是用户线程

七、线程同步

线程同步 = 队列 + 锁

synchronized

//锁的对象是变化的量,需要增删改的对象
public synchronized void function(){

}
synchronized(obj){

}

//JUC安全类型的集合
CopyOnWriteArrayList

lock

//定义lock锁
private final ReentrantLock lock = new ReentrantLock();

try{
	lock.lock();
	//代码块
}finally {
    lock.unlock();
}
//对比lock和synchronized

1.lock是显示锁、synchronized是隐式锁

2.lock只有代码块锁,synchronized有代码块锁和方法锁

八、死锁

//多个线程相互抱着对方需要的资源,然后形成僵持

技术分享图片

九、线程池

经常创建和销毁,使用量特别大的资源,比如并发情况下的线程,对性能影响很大

解决思路:提前创建好多个线程,放入线程池中,使用时直接获取,使用完放回池中。

好处:

  1. 提高响应速度
  2. 降低资源消耗
  3. 便于线程管理
//1.创建服务,创建线程池
ExecutorService service = Executors.newFixedThreadPool(10);
//2.执行
service.execute(new MyThread());//MyThread实现了Runnable
//3.关闭连接
service.shutdown();
---------------------------------------------------------------
//创建执行服务
ExecutorService ser = Executors.newFixedThreadPool(3);
//提交执行
Future<Boolean> r1 = ser.submit(t1);//t1 是Callable对象
Future<Boolean> r2 = ser.submit(t2);
Future<Boolean> r3 = ser.submit(t3);
//获取结果
boolean rs1 = r1.get();
boolean rs2 = r2.get();
boolean rs3 = r3.get();
//关闭连接
ser.shutdownNow();

多线程

原文:https://www.cnblogs.com/lk0528/p/13978964.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!