关于java多线程

关于同步与互斥

线程是进程的最小单元,同一进程中有多个线程
线程的交互有:互斥与同步

同步:因为线程之间的合作,如有线程A将计算结果提供给线程B作进一步处理,那么线程B在线程A将数据送达之前都将处于阻塞状态。

互斥:系统中的多个线程必然要共享某种系统资源,如共享CPU,共享I/O设备,所谓间接相互制约即源于这种资源共享,打印机就是最好的例子,线程A在使用打印机时,其它线程都要等待,这就是互斥

线程A和线程B互斥访问某个资源则它们之间就会产个顺序问题——要么线程A等待线程B操作完毕,要么线程B等待线程操作完毕,这其实就是线程的同步了

同步包括互斥,互斥是一种特殊的同步


线程的方法

这里写图片描述
互斥的实现:synckronized(lockObj–创建的锁对象)
lockObj.wait()方法是让线程等待,后面需要用lockObj.notify()或者lockObj.notyfyAll()方法使线程唤醒,这两个通常是成对出现的

如何理解同步 Wait Set(即线程等待区)

当一个线程获得资源的时候,会有锁,当线程获得的资源不够的时候,会调用wait()方法,释放获得的对象锁,并进入Wait Set区,让出资源来让后续的线程获取资源来做事,同第一个线程一样,后续的线程也有可能会wait(),也跟着进入了Wait Set区,当后续的线程执行的差不多了,结束了,要调用notify()去唤醒之前在Wait Set里的线程,或者notifyAll()唤醒所有线程重新抢占资源

演示代码如下:

这里写图片描述


线程同步经典问题重现:生产者与消费者模型

当生产者生产一个资源后,消费者消费一个资源,如果没有资源,消费者等待生产者生产资源

//生产者和消费者模型
//设置公共资源
class PublicResource{
    private int number=0;
    //增加公共资源
    //synchronize是关键字,同static用法,用在方法的前面,表示同步
    public synchronized void increase(){
        while(number!=0){
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        number++;
        System.out.println("生产1个资源,总资源为:"+number);
        notify();
    }
    //减少公共资源
    public synchronized void decrease(){
        while(number==0){
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
            number--;
            System.out.println("消耗1个资源,总资源为:"+number);
            notify();
    }
}
//创建生产者线程,负责生产资源
class ProducerThread implements Runnable{
    private PublicResource resource;
    public ProducerThread(PublicResource resource) {  
        this.resource = resource;  
    }  
    @Override
    public void run() {
        for(int i=0;i<10;i++){
            try {
                //睡眠0~1秒的时间
                Thread.sleep((long)(Math.random()*1000));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        resource.increase();
    }
}
//创建消费者线程,负责生产资源
class UserThread implements Runnable{
    private PublicResource resource;
    public UserThread(PublicResource resource) {  
        this.resource = resource;  
    }
    @Override
    public void run() {
        for(int i=0;i<10;i++){
            try {
                //睡眠0~1秒的时间
                Thread.sleep((long)(Math.random()*1000));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        resource.decrease();;
    }
}


//创建消费者

public class ProduceAndUse {

    public static void main(String[] args) {
        PublicResource resource = new PublicResource();  
        new Thread(new UserThread(resource)).start();  
        new Thread(new UserThread(resource)).start();  
        new Thread(new UserThread(resource)).start(); 
        new Thread(new ProducerThread(resource)).start();  
        new Thread(new ProducerThread(resource)).start();  
        new Thread(new ProducerThread(resource)).start();  
    }

}

结果为:
这里写图片描述

发布了25 篇原创文章 · 获赞 12 · 访问量 3万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章