JAVA多线程知识总结

1.概述

多线程:充分的利用计算机资源,同时执行不同的操作

1.计算机的操作系统。进程和线程
2.使用java来完成多线程的编码
3.线程中的常方法
4.线程同步(重点)
5.死锁
6.生产者消费者模型。异步

2.操作系统的简介

在这里插入图片描述
操作系统:本质就是一个运行在一堆硬件上的巨型软件
存在的意义:帮助上层应用程序屏蔽掉硬件的丑陋的接口
操作系统的发展史:
1.手工操作
2.批处理系统
3.多道批处理
4.分时系统
5.实时系统

进程和线程:

  • 进程:正在执行的程序,其实就是一块内存区域,内部存储这程序的资源
  • 线程:程序被CPU调度的最小单位,

3.java多线程

1继承Thread类,重写run方法
2.实现Runnable接口,实现run方法

必须:run(),start()
run():线程执行的时候执行的代码
start():启动一个线程

package Thread.MyThread;

public class myThread extends Thread {
    @Override
    public void run() {
        //要把子线程执行的内容写在run里
        for (int i = 0; i<1000;i++){
            System.out.println("我是子线程:"+i);
        }
    }
}

package Thread.MyThread;

public class Test {
    public static void main(String[] args) {//主线程
        //1.创建线程对象
        myThread mt = new myThread();

        //2.调用start()方法启动一个线程
       // mt.run();//方法的调用,不是启动线程
        mt.start();//继承自Thread类,启动一个线程-》子线程-》自动执行run()方法

        for (int i = 0; i<1000;i++){
            System.out.println(">>>>>>>我是主线程"+i);
        }
    }
}

package Thread.MyThread;

public class MyRunnable implements Runnable {
    @Override
    public void run() {
        for (int i = 0; i<1000;i++){
            System.out.println("我是子线程:"+i);
        }

    }
}

package Thread.MyThread;

public class Test1 {
    public static void main(String[] args) {
    //1.先创建Runnable的对象
        Runnable r = new MyRunnable();
        Thread t = new Thread(r);
        t.start();
        for (int i = 0; i<1000;i++){
            System.out.println("主线程:"+i);

        }
    }

}


4.线程相关操作

setPriority()设置优先级
1-10.5

package Thread.Prioity;

public class MyThread extends Thread{

    public MyThread(String name){
        super.setName(name);//设置线程的名字
    }
    @Override
    public void run() {
        for (int i = 0; i<500;i++){
            System.out.println(super.getName()+"==》"+i);
        }
    }
}
package Thread.Prioity;

public class Test {
    public static void main(String[] args) {
        MyThread mt1 = new MyThread("A线程");
        MyThread mt2 = new MyThread("B线程");


        mt2.setPriority(10);//有优先级,但不意味着独占cpu
        mt1.setPriority(4);//优先级低,但是不代表不执行
        mt1.start();
        mt2.start();
    }
}

sleep(毫秒)睡眠(重点)

package Thread.Sleep;

import java.text.SimpleDateFormat;
import java.util.Date;

public class MyThread extends Thread {
    @Override
    public void run() {
        while (true){
        //让子线程不断显示系统时间
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date d = new Date();
        System.out.println(sdf.format(d));
            try {
                Thread.sleep(1000);//睡眠1000毫秒----》1秒
            } catch (InterruptedException e) {

            }

        }
    }

    public static void main(String[] args) {
        MyThread mt = new MyThread();
        mt.start();


    }
}

每隔xxx时间去执行xxx工作

join()让主线程等待这个子线程执行完毕

package Thread.join;

public class MyThread extends Thread{
    @Override
    public void run() {
        for (int i = 0; i<1000;i++){
            System.out.println("子线程:"+i);
        }
    }
}
package Thread.join;

public class Test {
    public static void main(String[] args) {
        MyThread mt = new MyThread();
        mt.start();

        for (int i = 0; i<100;i++){
            System.out.println("主线程:"+i);
        }
        try {
            mt.join();//会让主线程等待子线程执行完毕,再继续执行
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
        }
        System.out.println("吼吼吼");
    }
}


yield()让出CPU,让别人执行一下

package Thread.yield;

public class MyThread extends Thread{
    public MyThread(String name){
        super.setName(name);
    }
    @Override
    public void run() {
        for(int i = 0;i<100;i++){
            if (i%10 ==0){
                Thread.yield();
            }
            System.out.println(super.getName()+":"+i);
        }
    }
}
package Thread.yield;

public class Test {
    public static void main(String[] args) {
        MyThread mt1 = new MyThread("A线程");
        MyThread mt2 = new MyThread("B线程");

        mt1.start();
        mt2.start();
    }
}

interrupt()打断正在睡眠中的线程

package Thread.inter;

public class Mythread extends Thread {
    @Override
    public void run() {
        System.out.println("我要睡觉了");
        try {
            Thread.sleep(100000000);
        } catch (InterruptedException e) {
            System.out.println("为什么不让睡了,醒了");
        }
        System.out.println("工作");
    }
}
package Thread.inter;

import Thread.yield.MyThread;

public class Test {
    public static void main(String[] args) {
       Mythread MT =new Mythread();
        MT.start();
        for (int i = 0;i<100;i++){
            System.out.println(i);
        }
        MT.interrupt();//打断正在睡眠中的子线程
    }
}

5.线程同步

线程同步:当多个线程共享一个资源的时候,我们可以在某一个线程访问到这个资源的时候,把这个资源暂时封锁,等待执行结束,释放这个锁,其他线程才可以进行操作,线程同步

总结:等待其他线程释放锁,让线程更加的安全

1.在方法声明上添加一个synchronized关键字
2.在方法内部使用synchronized(){}语句块对特定的对象上锁
3.手动上锁—》用的最少’
StringBuffer(有锁)和StringBuilder(无锁)

package Thread.sync;

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

public class Account {

    private double balance;//账户的钱
    private Lock lock = new ReentrantLock();//创建一个锁

    public Account(double balance){
        this.balance = balance;
    }
    public void  getMoney(){//一旦进入到该方法。瞬间锁定acc
        lock.lock();//上锁


            if (this.balance <= 0) {
                System.out.println("没钱了.");
                return;//回去
            }

            System.out.println("我要取钱了,目前还剩下:" + this.balance);
            this.balance -= 1000;
        System.out.println("取完了,还剩:"+this.balance);
        lock.unlock();//释放这个锁
        
    }
}

package Thread.sync;

public class GetMoneyThread extends Thread {
    private Account acc;
    //传进去
    public GetMoneyThread(Account acc){
        this.acc =acc;
    }

    @Override
    public void run() {
        acc.getMoney();
    }
}

package Thread.sync;

public class Test {
    public static void main(String[] args) {
        Account acc = new Account(1000);

        GetMoneyThread atm = new GetMoneyThread(acc);

        GetMoneyThread table = new GetMoneyThread(acc);

        atm.start();
        table.start();
    }
}

6.死锁

在这里插入图片描述

使用synchronized的时候一定要格外的注意,有没有互相调用的方法被锁定,慎重使用synchronized。

package Thread.dead;

public class DeadLock1 extends Thread {
    @Override
    public void run() {
        synchronized (ResourseObject.obj1){
            System.out.println("锁定第一个资源");
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            synchronized (ResourseObject.obj2){
                System.out.println("锁定第二个资源");
                System.out.println("锁定完毕");

            }
        }

    }
}
package Thread.dead;

import javax.jws.soap.SOAPBinding;

public class DeadLock2 extends Thread{
    @Override
    public void run() {
        synchronized (ResourseObject.obj2){
            System.out.println("锁定资源2");
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            synchronized (ResourseObject.obj1){
                System.out.println("锁定资源1");

                System.out.println("执行完毕");
            }
        }

    }
}
package Thread.dead;

public class ResourseObject {
    public static Object obj1 = new Object();
    public static Object obj2 = new Object();

}
package Thread.dead;

public class Test {
    public static void main(String[] args) {
        DeadLock1 dl1 = new DeadLock1();
        DeadLock2 dl2 = new DeadLock2();

        dl1.start();
        dl2.start();
    }
}

7.线程周期

在这里插入图片描述

8.生产者消费者

先读取视频,对视频内容进行鉴定-》发现违法内容,把该视频进行标记-》发送公安局
在这里插入图片描述
异步,左边不用等右边,右边不用等左边
生产者消费者模型:读取视频这一方被称为生产者,产品就是(小视频)右边发送给公安局就是消费者
Queue:队列。BlockingQueue阻塞队列,当队列中没有数据的时候,需要拿数据,队列会将程序阻塞,阻塞到有数据,队列继续工作。

package Thread.yellow;

/**
 * 产品,视频
 */
public class Video {
    private String name;
    public Video(String name){
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}



package Thread.yellow;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.atomic.AtomicInteger;

public class ReadVideoThread extends Thread {

    private static AtomicInteger i = new AtomicInteger();

    //准备能装视频的缓冲区(队列)
    private BlockingQueue<Video> videoQueue;

    public ReadVideoThread(BlockingQueue<Video> videoQueue){
        this.videoQueue = videoQueue;
    }
    @Override
    public void run() {
        while (true){
            String name = "苍老师"+i.incrementAndGet();
            Video v = new Video(name);//相当于i++

            try {
                videoQueue.put(v);//添加数据
                Thread.sleep(200);//让两个视频的执行效率不一样
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("发现了一个视频"+name);


        }
    }
}


package Thread.yellow;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.atomic.AtomicInteger;

public class SendYelloThread extends Thread {

    private  static AtomicInteger i = new AtomicInteger();

    private BlockingQueue<Video> videoQueue;

    public SendYelloThread(BlockingQueue<Video> videoQueue){
        this.videoQueue = videoQueue;
    }

    @Override
    public void run() {
        while (true){
            try {
                Video video = videoQueue.take();
                System.out.println("我是发送的地方,我发现了一个视频"+video.getName());
                Thread.sleep(150);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}


package Thread.yellow;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;

public class Test {
    public static void main(String[] args) {
        BlockingQueue<Video> videos = new LinkedBlockingDeque<Video>();

        ReadVideoThread rvt1 = new ReadVideoThread(videos);
        ReadVideoThread rvt2 = new ReadVideoThread(videos);
        ReadVideoThread rvt3 = new ReadVideoThread(videos);

        SendYelloThread syt1 = new SendYelloThread(videos);
        SendYelloThread syt2 = new SendYelloThread(videos);

        rvt1.start();
        rvt2.start();
        rvt3.start();
        syt1.start();
        syt2.start();
    }
}

练习

package Thread.HomeWork;

import java.util.List;
import java.util.Random;
import java.util.concurrent.atomic.AtomicInteger;

public class TableThread extends Thread {

    private List<Ticket>ticketList;

    private static AtomicInteger i = new AtomicInteger();

    public TableThread(List<Ticket> ticketList,String name){
        this.ticketList = ticketList;
        this.setName(name);//设置名字
    }

    @Override
    public void run() {
        while (true){
            if(i.get() + 4 < ticketList.size()){
            try {
                Thread.sleep(new Random().nextInt(150));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            Ticket t = ticketList.get(i.incrementAndGet());//i++
            System.out.println(this.getName()+"卖出:"+t.getName());//打印车票信息

            }else{
                System.out.println("卖完了");
                break;
            }
        }
}
}
package Thread.HomeWork;

public class Ticket {
    private int id;
    private String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Ticket(int id, String name){
        this.id = id;
        this.name = name;
    }
}

package Thread.HomeWork;

import java.util.ArrayList;
import java.util.List;

public class Test {
    public static void main(String[] args) {
        List<Ticket>ticketList = new ArrayList<Ticket>();

        for (int i = 0; i<1000;i++){
            Ticket t = new Ticket(i,"火车票"+i);
            ticketList.add(t);
        }
        //创建窗口
        TableThread tt1 = new TableThread(ticketList,"窗口一");
        TableThread tt2 = new TableThread(ticketList,"窗口二");
        TableThread tt3 = new TableThread(ticketList,"窗口三");
        TableThread tt4 = new TableThread(ticketList,"窗口四");

        tt1.start();
        tt2.start();
        tt3.start();
        tt4.start();


    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值