zoukankan      html  css  js  c++  java
  • 多线程入门(四)

    一、同步方法

    即有synchronized关键字修饰的方法。 由于java的每个对象都有一个内置锁,当用此关键字修饰方法时, 内置锁会保护整个方法。在调用该方法前,需要获得内置锁,否则就处于阻塞状态。

    注: synchronized关键字也可以修饰静态方法,此时如果调用该静态方法,将会锁住整个类。


    二、JDK5中Lock锁的使用


    Lock是一个接口,那么找它的实现类使用。

      虽然我们可以理解同步代码块和同步方法的锁对象问题,但是我们并没有直接看到在哪里加上了锁,在哪里释放了锁,
      为了更清晰的表达如何加锁和释放锁,JDK5以后提供了一个新的锁对象Lock。
      
      Lock:
       void lock(): 获取锁。
       void unlock():释放锁。  
      ReentrantLock是Lock的实现类.


    如下示例,明确知道在哪加锁和释放锁

    public class SellTicket implements Runnable {
    
    	// 定义票
    	private int tickets = 100;
    
    	// 定义锁对象
    	private Lock lock = new ReentrantLock();
    
    	@Override
    	public void run() {
    		while (true) {
    			try {
    				// 加锁
    				lock.lock();
    				if (tickets > 0) {
    					try {
    						Thread.sleep(100);
    					} catch (InterruptedException e) {
    						e.printStackTrace();
    					}
    					System.out.println(Thread.currentThread().getName()
    							+ "正在出售第" + (tickets--) + "张票");
    				}
    			} finally {
    				// 释放锁
    				lock.unlock();
    			}
    		}
    	}
    
    }


    三、死锁问题


    同步弊端

    效率低

    如果出现了同步嵌套,就容易产生死锁问题

    死锁问题及其代码

    是指两个或者两个以上的线程在执行的过程中,因争夺资源产生的一种互相等待现象

    同步代码块的嵌套案例


    四、线程间通信

    1.生产者消费者模型



    等待唤醒:
       Object类中提供了三个方法:
       wait():等待
      notify():唤醒单个线程
       notifyAll():唤醒所有线程
       为什么这些方法不定义在Thread类中呢?

       这些方法的调用必须通过锁对象调用,而我们刚才使用的锁对象是任意锁对象(随便的对象)。

      所以,这些方法必须定义在Object类中。


  • 相关阅读:
    Oracle86和92语法的连接,子查询,集合的操作
    Oracle笛卡尔积,分组,多表连接
    Oracle排序,伪列,字符函数,数字函数,日期行数
    Oracle基本的数据类型以及简单sql查询
    用while语句打印阶乘
    Switch小练习
    if语句多表达式与一个表达式
    三元操作符
    整数的二进制表达
    与或
  • 原文地址:https://www.cnblogs.com/chz-blogs/p/9380998.html
Copyright © 2011-2022 走看看