多线程学习笔记

本文详细介绍了Java中的线程概念,包括进程、线程的创建与执行,使用Thread和Runnable创建线程,以及Callable接口实现带返回值的线程。还探讨了线程的状态、线程同步(如synchronized和Lock),线程通信的wait/notify机制,以及线程池的工作原理和配置。此外,提到了线程的优先级、守护线程和死锁问题,展示了如何避免和处理这些问题。
摘要由CSDN通过智能技术生成

线程,进程,多线程

1.进程:每个应用程序都是一个进程
2.线程:每个进程至少包含一个线程,线程接受CPU的调度

Thread

package com.zwj.thread;

/**
 * @author zwj
 * @date 2022/2/18 - 11:03
 */
public class MyThread extends Thread{

    @Override
    public void run() {

        for (int i = 0; i < 100; i++) {
            System.out.println("MyThread:"+i);
        }

    }
}

package com.zwj.thread;

/**
 * @author zwj
 * @date 2022/2/18 - 11:04
 */
public class Test {
    public static void main(String[] args) {
        Thread thread = new MyThread();
        thread.start();
        for (int i = 0; i < 100; i++) {
            System.out.println("main:"+i);
        }
    }
}

Runnable

package com.zwj.runnable;

/**
 * @author zwj
 * @date 2022/2/18 - 11:07
 */
public class MyRunnable implements Runnable{

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("MyRunnable:"+i);
        }
    }
}

package com.zwj.runnable;

/**
 * @author zwj
 * @date 2022/2/18 - 11:08
 */
public class Test {
    public static void main(String[] args) {
        Runnable runnable = new MyRunnable();
        Thread thread = new Thread(runnable);
        thread.start();
        for (int i = 0; i < 100; i++) {
            System.out.println("main:"+i);
        }
    }
}

Callable

可以有返回值
package com.zwj.callable;

import java.util.concurrent.Callable;

/**
 * @author zwj
 * @date 2022/2/18 - 11:11
 */
public class MyCallable implements Callable<Boolean> {

    private String name;

    public MyCallable(String name) {
        this.name = name;
    }

    @Override
    public Boolean call() throws Exception {
        for (int i = 0; i < 100; i++) {
            System.out.println("MyCallable-"+name+":"+i);
        }
        return true;
    }
}

package com.zwj.callable;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledThreadPoolExecutor;

/**
 * @author zwj
 * @date 2022/2/18 - 11:14
 */
public class Test {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        MyCallable m1 = new MyCallable("1");
        MyCallable m2 = new MyCallable("2");
        MyCallable m3 = new MyCallable("3");

        //创建线程池
        ExecutorService service = new ScheduledThreadPoolExecutor(3);

        //提交线程
        Future<Boolean> submit1 = service.submit(m1);
        Future<Boolean> submit2 = service.submit(m2);
        Future<Boolean> submit3 = service.submit(m3);

        Boolean aBoolean = submit1.get();
        Boolean aBoolean1 = submit2.get();
        Boolean aBoolean2 = submit3.get();

        //关闭线程池
        service.shutdown();

    }
}

线程状态

1.创建状态: new 线程
2.就绪状态: start()方法
3.阻塞状态: sleep()方法或者wait()方法或者同步锁,解除后才能重新被cpu调度
4.运行状态: 执行代码块
5.死亡状态: 线程中断或执行完毕

sleep和wait的区别

1.sleep方法来自Thread类,wait来自Object类
2.sleep方法不会释放锁,wait方法会释放所有锁
3.sleep方法阻塞到时间后会自动重新竞争cpu资源,wait需要等待其他线程调用notify/notifyAll方法唤醒线程
4.notify()随机唤醒一个线程,notifyAll()唤醒所有线程
5.sleep必须捕获异常,而wait,notify和notifyAll不需要捕获异常

yield

礼让线程
让出当前占用的CPU资源,重新进入就绪状态竞争资源,有可能重新被选中,导致礼让不成功

join

线程插队
在其他线程启动前调用join方法,强制插队执行,直接抢夺CPU,执行完毕才释放资源
调用位置必须写好,只有在线程start后调用才有效果
package com.zwj.join;

/**
 * @author zwj
 * @date 2022/2/18 - 11:40
 */
public class JoinThread implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            if (Thread.currentThread().getName().equals("thread1")){
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println(Thread.currentThread().getName()+i);
        }
    }

    public static void main(String[] args) throws InterruptedException {
        JoinThread joinThread = new JoinThread();

        Thread thread1 = new Thread(joinThread,"thread1");
        Thread thread2 = new Thread(joinThread,"thread2");
        Thread thread3 = new Thread(joinThread,"thread3");

        thread1.start();
        thread1.join();
        thread2.start();
        thread3.start();

    }
}

线程优先级

线程优先级并不能保证线程一定会优先执行,只是概率大了,因为最终的选择由CPU决定,无法认为参与

//设置线程优先级
thread.setPriority()

守护线程

1.虚拟机必须保证用户线程执行完毕,虚拟机不用等待守护线程执行完毕
2.如后台记录操作日志,垃圾回收,监控内存

线程同步(锁)

synchronised (排他锁)  同步方法和同步代码块
Lock锁:JDK1.5之后出现,显式同步锁 手动解锁 可重入锁  
package com.zwj.lock;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author zwj
 * @date 2022/2/18 - 13:47
 */
public class MyLockThread implements Runnable{
    
    //票
    int ticketNum = 10;

    //定义Lock锁
    private final Lock lock = new ReentrantLock();
    
    @Override
    public void run() {
        try {
            lock.lock();  //加锁
            while(ticketNum>0){
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(ticketNum--);
            }
        }finally {
            lock.unlock();
        }
        
    }
}

死锁  多个线程各自占用的资源都是对方想要的,导致僵持住,然后形成死锁,代码无法继续运行下去
	形成死锁的四个条件:
		1.互斥条件:一个资源一次只能被一个进程使用
		2.请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放
		3.不剥夺条件:进程已获得的资源,在未使用完之前,不能被强行剥夺
		4.循环等待资源:若干进程之间形成一种头尾相接的循环等待资源关系

线程通信

1.wait 和 notify notifyAll 进行线程通信,唤醒线程
2.使用基于线程安全的List做数据缓冲区

线程池

线程池七个参数:
	1.corePoolSize: 核心池大小,核心线程不会被回收
	2.maximumPoolSize: 最大线程数
	3.keepAliveTime:空闲线程存活时间,线程超过空闲时间,会被回收只剩核心线程
	4.unit:时间单位  keepAliveTime的时间单位
	5.workQueue:工作队列,存放待执行任务的队列:当提交的任务数超过核心线程数大小后,再提交的任务就存放在工作队列,任务调度时再从队列中取出任务。它仅仅用来存放被execute()方法提交的Runnable任务,五种队列	
	6.threadFactory:线程工厂
	7.handler:拒绝策略
		1)丢弃抛异常
		2)丢弃不抛异常
		3)丢弃队列最前面的任务
		4)由调用线程执行该任务
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值