Java教程

java多线程

本文主要是介绍java多线程,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

java多线程

文章目录

  • java多线程
    • 线程状态
    • 线程方法
    • 停止线程
    • 线程休眠
    • 线程礼让
    • 线程强制执行
    • 线程优先级
    • 守护线程
      • 设置线程是否为用户或者守护线程
    • 并发
    • 线程同步
      • 同步块
    • CopyOnWriteArrayList
    • 死锁
      • 死锁避免
    • 锁(LOCK)
    • 生产者消费者(线程通信)

线程状态

线程状态图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-e0oECrhZ-1630902888153)(C:\Users\HJX\AppData\Roaming\Typora\typora-user-images\image-20210905115238990.png)]

线程方法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6tVQ07De-1630902888155)(C:\Users\HJX\AppData\Roaming\Typora\typora-user-images\image-20210905115443263.png)]

停止线程

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xRKoR1Gx-1630902888156)(C:\Users\HJX\AppData\Roaming\Typora\typora-user-images\image-20210905115630808.png)]

线程休眠

注意:线程休眠sleep并不会释放锁,即当前的cpu仍然调度该线程

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eR3vlbFX-1630902888158)(C:\Users\HJX\AppData\Roaming\Typora\typora-user-images\image-20210905120353422.png)]

在这里插入图片描述

线程礼让

礼让不一定成功。

在这里插入图片描述

package com.Thread;
//线程礼让
public class Test_Yield implements Runnable{
    @Override
    public void run(){
        System.out.println(Thread.currentThread().getName()+"正在执行");
        //线程礼让 不一定成功,看cpu心情
        Thread.yield();
        System.out.println(Thread.currentThread().getName()+"执行完毕");
    }

    public static void main(String[] args) {
        Test_Yield test_yield=new Test_Yield();
        new Thread(test_yield,"线程a").start();
        new Thread(test_yield,"线程b").start();
    }
}

线程强制执行

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gcKQi4Ap-1630902888160)(C:\Users\HJX\AppData\Roaming\Typora\typora-user-images\image-20210905123859190.png)]

package com.Thread;

public class Test_Join implements Runnable{
    @Override
    public void run(){
        for(int i=0;i<10;i++){
            System.out.println((i+1)+"---vip来了,你们都给我让路");
        }
    }
    public static void main(String[] args) {
            Test_Join test_join=new Test_Join();
            Thread thread=new Thread(test_join);
            thread.start();
            for(int j=0;j<5;j++){
                if(j==3){
                    try {
                        //等待子线程thread执行完后 再执行主线程
                        thread.join();
                    }catch (InterruptedException e){
                        e.getMessage();
                    }
                }
                System.out.println("main---"+(j+1));
            }
    }
}

线程优先级

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gHmpg3hb-1630902888161)(C:\Users\HJX\AppData\Roaming\Typora\typora-user-images\image-20210905132556531.png)]

注意:一定要先设置优先级再启动。

优先级高的不一定先执行,但是大多数情况优先级高的会先执行。通过优先级你可以将需要先执行的代码块设置成高优先级。

守护线程

设置线程是否为用户或者守护线程

通过Thread.setDaemon(false)设置为用户线程
通过Thread.setDaemon(true)设置为守护线程

守护线程的定义:

是指在程序运行的时候在后台提供一种通用服务的线程,比如垃圾回收线程就是一个很称职的守护者,并且这种线程并不属于程序中不可或缺的部分。因此,当所有的非守护线程结束时,程序也就终止了,同时会杀死进程中的所有守护线程。反过来说,只要任何非守护线程还在运行,程序就不会终止。

用户线程定义

指不需要内核支持而在用户程序中实现的线程,其不依赖于操作系统核心,应用进程利用线程库提供创建、同步、调度和管理线程的函数来控制用户线程。这种线程甚至在象 DOS 这样的操作系统中也可实现,但线程的调度需要用户程序完成,这有些类似 Windows 3.x 的协作式多任务。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RysvGwY0-1630902888162)(C:\Users\HJX\AppData\Roaming\Typora\typora-user-images\image-20210905134850264.png)]

package com.Thread;

public class Guard_Thread{
    public static void main(String[] args) {
        People people=new People();
        God god=new God();
        Thread p=new Thread(people);
        Thread God=new Thread(god);
        //将线程God设置为守护线程 虚拟机不必等待守护线程执行完毕
        God.setDaemon(true);

        p.start();
        God.start();

    }
}

class People implements Runnable{
    @Override
    public void run(){
        for(int i=1;i<=36500;i++){
            System.out.println("今天第是"+i+"天");
        }
    }
}

class God implements Runnable{
    @Override
    public void run(){
        while (true){
            System.out.println("上帝God");
        }
    }
}


并发

线程同步

在这里插入图片描述

同步块

CopyOnWriteArrayList

测试JUC安全类型集合

死锁

如下示例:

package com.DeadLock;

public class DeadLock{
    public static void main(String[] args) {
        Makeup girl1=new Makeup(0,"灰姑凉");
        Makeup girl2=new Makeup(1,"白雪公主");
        girl1.start();
        girl2.start();
    }
}

//口红
class lipstick{

}

//化妆
class Mirror{

}



class Makeup extends Thread{
    //口红
    static lipstick l=new lipstick();
    //镜子
    static Mirror mirror=new Mirror();
    int choice;
    String girlName;
    Makeup(int choice,String girlName){
        this.choice=choice;
        this.girlName=girlName;
    }
    @Override
    public void run(){
        //化妆
        try{
            makeup();
        }catch (InterruptedException e){
            e.printStackTrace();
        }
    }
    //化妆的方法 互相持有对方的锁,需要拿到对方的资源
    private void makeup() throws InterruptedException{
        if(choice==0){
            synchronized (l){ //获得口红的锁
                System.out.println(this.girlName+"获得口红的锁");
                Thread.sleep(1000);
                //获得镜子的锁
//                synchronized (mirror){
//                    System.out.println(this.girlName+"获得镜子的锁");
//                }
            }
            //拿到外面来就不会死锁了
            synchronized (mirror){
                System.out.println(this.girlName+"获得镜子的锁");
            }
        }else {
            synchronized (mirror){ //获得口红的锁
                System.out.println(this.girlName+"获得镜子的锁");
                Thread.sleep(1000);
                //获得镜子的锁
//                synchronized (l){
//                    System.out.println(this.girlName+"获得口红的锁");
//                }
            }
            //拿到外面来就不会死锁了
            synchronized (l){
                System.out.println(this.girlName+"获得口红的锁");
            }
        }

    }
}

死锁避免

锁(LOCK)

示例代码:

package com.DeadLock;

import java.util.concurrent.locks.ReentrantLock;

//ReentrantLock:可重入锁


public class TestLock {
    public static void main(String[] args) {
        TestLock2 testLock2=new TestLock2();
        new Thread(testLock2).start();
        new Thread(testLock2).start();
        new Thread(testLock2).start();
    }
}

class TestLock2 implements  Runnable{
    private int tickesNum=10;
    //定义Lock锁
    private final ReentrantLock Lock=new ReentrantLock();




    @Override
    public void run(){
        while (true){
            try {
                Lock.lock(); //加锁
                if(tickesNum>0){
                    try{
                        Thread.sleep(1000);

                    }
                    catch (InterruptedException e){
                        e.printStackTrace();
                    }
                    System.out.println(tickesNum--);
                }else{
                    return;
                }

            }finally {

                Lock.unlock();  //解锁
            }

        }
    }
}

synchronized域Lock的对比

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Gi3liICl-1630902888163)(C:\Users\HJX\AppData\Roaming\Typora\typora-user-images\image-20210905210523110.png)]

生产者消费者(线程通信)

这篇关于java多线程的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!