Java 多线程操作

本文深入解析了多线程的基本概念,包括并发与并行的区别,进程与线程的特性,以及多线程的实现方式。同时,探讨了多线程可能引发的线程安全问题及解决方案,如同步代码块、同步方法和ReentrantLock的使用。并通过生产者和消费者模式,展示了线程间的通信机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在介绍多线程之前,先介绍并发和并行的区别:

并发:是指在某一段时间内发生多个事件;

并行:是指在同一时刻发生多个事件;

在操作系统中,有多个CPU,可以并发进行多程序的并发执行,而单CPU,只能进行CPU资源的调度,并行执行程序;

进程和线程的区别:

进程:拥有自己独立的内存空间;

线程:最小的CPU调度单位

多线程实现方式:

1)继承于java.lang.Thread

  • 定义类,修改run方法;
  • 在其他线程过程中启动,start

2)Runnable接口实现类

注意:这里仅仅只是一个接口实现类,修改run方法,在启动线程时需要new Thread(),先创建线程对象,然后再start启动线程;

多线程带来的问题:

当多线程并发去访问同一份资源的时候,可能会引发线程安全的问题;

目前解决方案:

1)同步代码块

      synchronized(监听对象)

2)同步方法

      synchronize修饰

      同步方法为static,则监听对象是当前对象的字节码对象object.class;

      同步方法为非static,则监听对象是this

3)lock

     通常使用ReentrantLock类,一种可重入的互斥锁

线程通信

常见的就是生产者和消费者案例,两者共用同一块数据资源。

1)写的过程和读的过程都要同步;

2)不能出现生产一个,消费多个的情况;

在Object类中,操作线程的方法:
  都得使用当前同步监听对象来调用,否则报错IllegalMonitorStateException:
解决问题2就是需要监听共享区域是否为空,为空消费者线程就应该等待,不为空则生产者线程就得等待;也可以使用Lock和condition机制;condition.await()和condition.signal();

void wait():让当前线程失去同步监听对象,进入无限制的等待,除非其他线程唤醒它,不然永远醒不过来.

void notify() :唤醒在此同步监听对象上等待的一个线程

void notifyAll():唤醒在此同步监听对象上等待的所有线程.

//生成者
public class Product implements Runnable{

    //生成者

    private ShareResource share = null;

    Product(ShareResource share){
        this.share = share;
    }

    @Override
    public void run() {
        for(int i=0;i<100;i++){
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if(i%2 == 0){
                share.push("a", "girl");
            }else{
                share.push("b", "boy");
            }
        }
    }
}

//消费者
public class Consumer implements Runnable {
    private ShareResource share;

    Consumer(ShareResource share){
        this.share = share;
    }

    @Override
    public void run() {
        for(int i =0;i<100;i++){
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            share.popup();
        }
    }
}

// 共享空间

public class ShareResource {

    private String name;
    private String gender;
    private boolean isEmpty = true;  // 开始共享空间为空

    synchronized public void push(String name, String gender){
        while(!isEmpty){
            try {
                this.wait();  //等待
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        this.name = name;
        this.gender = gender;
        isEmpty = false;
        this.notify();  // 唤醒其他线程
    }

    synchronized public void popup(){
        while(isEmpty){
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println(this.name + "--" + this.gender);
        isEmpty = true;
        this.notifyAll();  // 唤醒其他所有线程
    }
}


//测试类

public class App {

    public static void main(String[] args){
        ShareResource shareResource = new ShareResource();

        new Thread(new Product(shareResource), "Product").start();

        new Thread(new Consumer(shareResource), "Consumer1").start();

        new Thread(new Consumer(shareResource), "Consumer2").start();
    }
}

 

线程类型:

join方法----联合线程

setDaemon ---- 后台线程

 

线程优先级:

每个线程都有优先级,优先级的高低只和线程获得执行机会的次数多少有关,并非线程优先级越高的就一定先执行,哪个线程的先运行取决于CPU的调度

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值