多线程详解
线程创建
ThreadRunnableCallable 静态代理Lambda表达式停止线程线程休眠(sleep)线程礼让(Yield)线程强制执行(Join)守护(daemon)线程线程同步机制死锁Lock锁
Lock锁与synchronized锁的对比 线程池
多线程详解线程就是独立执行的路径
main线程是主线程
线程创建
Thread class — 继承Thread类(重点)
Runnable接口 — 实现Runnable接口(重点)
Callable接口 — 实现Callable接口(了解即可)
Thread继承Thread类,重写run()方法,调用start开启线程
//创建线程方式一:
public class TestThread01 extends Thread{
@Override
public void run() {
//run方法线程体
for (int i = 0; i < 10; i++) {
System.out.println("看看代码-->"+i);
}
}
public static void main(String[] args) {
//创建一个线程对象
TestThread01 testThread01 = new TestThread01();
//调用start方法开启线程
testThread01.start();
// testThread01.run();
//main线程,主线程
for (int i = 0; i < 10; i++) {
System.out.println("学习线程-->"+i);
}
}
}
Runnable
实现Runnable接口,重写run()方法,执行接口需要丢入Runnable接口实现类,调用start方法
//创建线程方式二:
public class TestThread02 implements Runnable{
@Override
public void run() {
//run方法线程体
for (int i = 0; i < 10; i++) {
System.out.println("看看代码-->"+i);
}
}
public static void main(String[] args) {
//创建Runnable接口的实现类对象
TestThread02 testThread02 = new TestThread02();
//创建线程对象,通过线程对象来开启我们的线程,‘代理’
// Thread thread = new Thread(testThread02);
// thread.start();
new Thread(testThread02).start();
//main线程,主线程
for (int i = 0; i < 10; i++) {
System.out.println("学习线程-->"+i);
}
}
}
多个线程同时操一个对象
//买票例子
public class TestThread03 implements Runnable {
//票数
private int ticketNums = 10;
@Override
public void run() {
while (true){
if(ticketNums<=0){
break;
}
System.out.println(Thread.currentThread().getName()+"-->拿到了第"+ticketNums--+"张票");
}
}
public static void main(String[] args) {
TestThread03 ticket = new TestThread03();
new Thread(ticket,"王宝强").start();
new Thread(ticket,"黄渤").start();
new Thread(ticket,"徐峥").start();
}
}
Callable
实现Callable接口,需要返回值类型
重写call方法,需要抛出异常
创建执行服务
提交执行
获取结果
关闭执行
静态代理
代理类和被真实类应该共同实现一个接口,或者是共同继承某个类。
点击跳转到静态代理说明
Lambda表达式
避免匿名内部类过多
其实质属于函数式编程的概念
new Thread(( )-> System.out.println("i like lambda")).start();
前提是接口为函数式接口(interface)
public class TestLambda01 {
public static void main(String[] args) {
//lambda简化
ILove love = (int a)->{
System.out.println("i love you-->"+a);
};
love.love(520);
//简化1:参数类型
love = (a)->{
System.out.println("i love you-->"+a);
};
love.love(521);
//简化2:简化括号
love = a ->{
System.out.println("i love you-->"+a);
};
love.love(522);
//简化3:去掉花括号
love = a-> System.out.println("i love you-->"+a);
love.love(523);
}
}
interface ILove{
void love(int a);
}
lambda表达式如果有多行,就用代码块包裹
停止线程
不推荐使用JDK提供的stop( )、destroy( )方法。【已废弃】推荐线程自己停下来建议使用一个标志位进行终止变量,当flag=flase,则终止线程运行
线程休眠(sleep)
sleep(时间)指定当前线程阻塞的毫秒数
sleep存在异常InterruptedException
sleep时间达到后线程进入就绪状态
sleep可以模拟网络延时,倒计时等
每一个对象都有一个锁,sleep不会释放锁
//模拟延时
try {
Thread.sleep(100);
}catch (InterruptedException e){
e.printStackTrace();
}
//模拟倒计时
public class TestSleep {
public static void main(String[] args) {
try {
Tendown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void Tendown() throws InterruptedException{
int num = 10;
while (true){
Thread.sleep(1000);
System.out.println(num--);
if (num<=0){
break;
}
}
}
}
线程礼让(Yield)
礼让线程,让当前正在执行的线程暂停,但不阻塞将线程从运行状态转换为就绪状态让CPU重新调度,礼让不一定成功,看CPU心情
线程强制执行(Join)
Join合并线程,待此线程执行完成后,再执行其他线程,其他线程堵塞
可以看成插队
public class TestJoin implements Runnable{
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("线程vip来了"+i);
}
}
public static void main(String[] args) throws InterruptedException {
//启动线程
TestJoin testJoin = new TestJoin();
Thread thread = new Thread(testJoin);
thread.start();
//主线程
for (int i = 0; i < 100; i++) {
if (i == 20){
thread.join();
}
System.out.println("main"+i);
}
}
}
守护(daemon)线程
线程分为用户线程和守护线程
虚拟机必须确保用户线程执行完毕
虚拟机不用等待守护线程执行完毕
//守护线程
//上帝保佑你
public class TestDaemon {
public static void main(String[] args) {
God god = new God();
You you = new You();
Thread thread = new Thread(god);
thread.setDaemon(true);//默认是false,表示用户线程,正常线程都是用户线程
thread.start(); //上帝守护线程启动
new Thread(you).start(); //你 用户线程启动
}
}
//上帝
class God implements Runnable{
@Override
public void run() {
while (true){
System.out.println("上帝保佑着你!");
}
}
}
//你
class You implements Runnable{
@Override
public void run() {
for (int i = 0; i < 365; i++) {
System.out.println("你开心的活着!");
}
System.out.println("====goodbye world====");
}
}
线程同步机制
并发(同一个对象被多个线程同时操作)队列 和 锁(synchronized)
死锁
死锁:多个线程互相抱着对方需要的资源,形成僵持程序中要避免死锁这是会产生死锁的情况
这是避免死锁的情况
Lock锁
class A{
private final ReentrantLock lock = new ReentrantLock();
public void m(){
lock.lock(); //加锁
try {
//保证线程安全的代码
}finally {
lock.unlock(); //解锁
//如果同步代码有异常,要将unloc()写入finally语句块
}
}
}
ReentrantLock:可重入锁
Lock锁与synchronized锁的对比Lock是显式锁,synchronized是隐式锁Lock只有代码块锁,synchronized有代码块锁和方法锁使用Lock锁,JVM使用较少的时间来调度线程,性能更好
线程池
创建多个线程放入线程池中,使用时直接获取,使用完放回池中。
避免频繁创建销毁,实现重复利用
好处
提高响应速度降低资源消耗便于线程管理
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
//线程池
public class TestPool {
public static void main(String[] args) {
//1.创建线程池
//newFixedThreadPool 参数为:线程池大小
ExecutorService service = Executors.newFixedThreadPool(10);
//执行
service.execute(new MyThread());
service.execute(new MyThread());
service.execute(new MyThread());
service.execute(new MyThread());
//关闭链接
service.shutdown();
}
}
class MyThread implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
}
这里是果力成,欢迎你的到来阅读,持续学习!
帅的人已经点点关注了~~



