JAVA线程的同步与互斥

原创 2015年11月23日 22:25:49

1、什么是同步,互斥。
同步一般有互斥一起讨论。在多道程序设计的操作系统中,由于存在并发执行(多个进程抢占一处理机的使用权),所以各个进程间的存在资源共享和相互合作的问题。而同步就是进程间的直接制约问题互斥是申请临界资源进程间的间接制约问题


2、什么是线程。
由于进程是一个拥有资源的独立单位,在各个进程抢夺处理机的被调度的过程会,系统会付出较大的时间开销,所引入了纯程,将纯程作为调度和分配资源的基本单位,用户可以通过创建线程完成任务,以减少系统开销。打开任务管理器(Ctrl+Shift+Esc),进程选项卡里正在运行的就是当前所有进程。


3、生产商与消费者(同步)
多个生产商与多个消费者共用一个仓库,这个仓库就是临界资源,生产商会不断的生产商品,消费者同样也在不断的消费,但当仓库满仓时,生产商应该停止生产了(wait()),但消费者同时还在不断的消费,当仓库有空闲仓位时,生产商就应该被唤醒(notify()),继续生产。同样消费者也是,当仓库没有商品时,消费者也应该停止消费,等生产商生产出商品后,才继续消费。


class Store {
    // 仓位最多为20个
    private final int MAX = 20;
    private int num = 0;

    /**
     * 生产商生产的产品入库
     */
    public synchronized void produce(Producer producer) {
        while (num == MAX) {
            try {
                System.out.println("仓库已满 ,请等待空位");
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        ++num;
        System.out.println(producer.name+" 生产了后,仓库现存 :" + num+"个产品");
        notify();//唤醒其它进程
    }

    /**
     * 消费者消费商品出库
     */
    public synchronized void consume(Comsumer consumer) {
        while (num == 0) {
            try {
                System.out.println("仓库空仓,请等待产品入库");
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        --num;
        System.out.println(consumer.name+" 消费后,还剩 :" + num+"个产品");
        notify();//唤醒其它进程
    }
}

/**
 * 生产商类,不断地生产产品
 */
class Producer implements Runnable {
    String name;
    Store store;

    public Producer(String name,Store store) {
        this.name=name;
        this.store = store;
    }

    @Override
    public void run() {
        while (true) {
            try {
                Thread.sleep((long) (Math.random() * 1000));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            store.produce(this);
        }
    }

}

/**
 * 消费者类,不断地消费产品
 */
class Comsumer implements Runnable {
    String name;
    Store store;
    public Comsumer(String name,Store store) {
        this.name = name;
        this.store=store;
    }

    @Override
    public void run() {
        while (true) {
            try {
                Thread.sleep((long) (Math.random() % 30 * 1000));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            store.consume(this);
        }
    }

}

public class Main {

    public static void main(String[] args) {
        Store store = new Store();
        new Thread(new Comsumer("张三",store)).start();
        new Thread(new Comsumer("李四",store)).start();
        new Thread(new Comsumer("王五",store)).start();
        new Thread(new Producer("第一工厂",store)).start();
        new Thread(new Producer("第二工厂",store)).start();
        new Thread(new Producer("第三工厂",store)).start();
    }
}

4、车票售卖(互斥)
一个车站有多个售票窗口,如果每个售票窗口就相当于一个线程,车票就是互斥线程争夺的临界资源。为了保障信息的完整性、安全性和封闭性。所以对于临界资源必须保护起来。在java语言中就是加synchronized关键字,告诉系统,这是一个临界资源,一个只能一个线程访问。如果不加synchronized关键字,就有可能出现数据丢失或读取脏数据的错误。就以下代码,如果sale()方法没有加synchronized关键字,num就可能输出-1,-2等错误的数据,但事实上,车票是没有负数的。


class Ticket {
    private int num = 10;

    /**
     * sale()方法代表销售车票,如果不加synchronized关键字,可能有负数输出
     */
    public synchronized void sale(Window window) {
        if (num > 0) {
            // 输出当前有多少张车票
            System.out.println(window.name + "售出票,还剩 :" + --num);
        } else {
            try {
                // 车票售完后,所有线程等待
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

}

/**
 * 窗口类
 */
class Window implements Runnable {
    String name;
    Ticket ticket;

    public Window(String name, Ticket ticket) {
        super();
        this.name = name;
        this.ticket = ticket;
    }

    @Override
    public void run() {
        while (true) {
            try {
                // 等待[0,3)秒
                long time = (long) (Math.random() * 3) * 1000;
                Thread.sleep(time);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            ticket.sale(this);
        }
    }
}

public class Main {
    public static void main(String[] args) {
        Ticket t = new Ticket();
        // 三个售票窗口,相当三个互斥线程
        new Thread(new Window("窗口一", t)).start();
        new Thread(new Window("窗口二", t)).start();
        new Thread(new Window("窗口三", t)).start();
    }
}

在eclipse中的运行结果
这里写图片描述

JAVA多线程机制之同步与互斥

一个多线程的程序,两个或者多个线程可能需要访问同一个数据资源。这时就必须考虑数据安全的问题,需要线程互斥或者同步。线程的互斥当多个线程需要访问同一资源时,要求在一个时间段内只能允许一个线程来操作共享资...
  • jianggujin
  • jianggujin
  • 2016年01月04日 20:12
  • 3557

【Java】线程并发、互斥与同步

网络上对于线程的解析总是天花龙凤的,给你灌输一大堆概念,考研、本科的操作系统必修课尤甚,让你就算仔细看完一大堆文章都不知道干什么。 下面不取网站复制粘贴,在讲解自己的Java线程并发、互斥与同步之前先...
  • yongh701
  • yongh701
  • 2015年01月17日 09:22
  • 2588

多线程同步与互斥(3)

在进行多线程编程时,难免还要碰到两个问题,那就线程间的互斥与同步: 线程同步是指线程之间所具有的一种制约关系,一个线程的执行依赖另一个线程的消息,当它没有得到另一个线程的消息时应等待,直到消息到达时...
  • Xp275500976
  • Xp275500976
  • 2012年02月02日 10:02
  • 16162

java的线程问题同步与互斥

1.java实现线程的方法;    1.实现Runnable接口,重写run方法,通过Thread的start方法启动线程。这种方法可以实现资源的共享    2.继承Thread类,重写run方法  ...
  • wj903829182
  • wj903829182
  • 2014年08月07日 23:21
  • 963

【Linux多线程】同步与互斥的区别

很多人把同步与互斥这两个概念混淆,这里说一下它们的区别。一、同步与互斥的区别1. 同步同步,又称直接制约关系,是指多个线程(或进程)为了合作完成任务,必须严格按照规定的 某种先后次序来运行。例如,线程...
  • lisong694767315
  • lisong694767315
  • 2015年04月29日 23:11
  • 6647

线程同步与互斥:互斥锁

为什么需要互斥锁? 在多任务操作系统中,同时运行的多个任务可能都需要使用同一种资源。这个过程有点类似于,公司部门里,我在使用着打印机打印东西的同时(还没有打印完),别人刚好也在此刻使用打印机打印...
  • lianghe_work
  • lianghe_work
  • 2015年08月18日 09:59
  • 9314

多线程中的互斥与同步

package bxjg; /** * 宇宙的能量系统 * 遵循能量守恒定律: * 能量不会凭空创生或消失,只会从一处转移到另一处 */ public class EnergySystem ...
  • u014451076
  • u014451076
  • 2015年11月08日 11:32
  • 353

生产者与消费者模式(线程的同步与互斥)

条件变量 条件变量的提出首先要涉及一个概念,就是生产者消费者模型: 生产者消费者,是在多线程同步的一个问题,两个固定大小缓冲区的线程,在实际运行是会发生问题,生产者是生成数据放入缓冲区,重复过程...
  • hj605635529
  • hj605635529
  • 2017年04月05日 15:27
  • 268

同步和异步。同步和互斥

同步就是多个线程同时访问一块资源,而且
  • err118
  • err118
  • 2014年11月24日 15:59
  • 737

java同步和互斥

来源:http://blog.csdn.net/lazy_tiger/article/details/1820582   Java关键字synchronized是Java 语言提供的对多线程和同...
  • chunqiuwei
  • chunqiuwei
  • 2012年05月31日 22:38
  • 6229
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:JAVA线程的同步与互斥
举报原因:
原因补充:

(最多只允许输入30个字)