zoukankan      html  css  js  c++  java
  • 69期-Java SE-014_多线程-3-001-002

    ### 死锁
    
    死锁是一种错误,实际开发中需要注意避免这种错误的出现。
    
    ```java
    public class Chopsticks {
    
    }
    ```
    
    ```java
    public class DeadLockRunnable implements Runnable {
        public int num;
        private static Chopsticks chopsticks1 = new Chopsticks();
        private static Chopsticks chopsticks2 = new Chopsticks();
    
        @Override
        public void run() {
            // TODO Auto-generated method stub
            if(num == 1) {
                System.out.println(Thread.currentThread().getName()+"获取到chopsticks1,等待获取chopsticks2");
                synchronized (chopsticks1) {
                    try {
                        Thread.currentThread().sleep(100);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    synchronized (chopsticks2) {
                        System.out.println(Thread.currentThread().getName()+"用餐完毕");
                    }
                }
            }
            
            if(num == 2) {
                System.out.println(Thread.currentThread().getName()+"获取到chopsticks2,等待获取chopsticks1");
                synchronized (chopsticks2) {
                    try {
                        Thread.currentThread().sleep(100);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    synchronized (chopsticks1) {
                        System.out.println(Thread.currentThread().getName()+"用餐完毕");
                    }
                }
            }
            
        }
    
    }
    ```
    
    ```java
    
    public class Test {
        public static void main(String[] args) {
            DeadLockRunnable deadLockRunnable1 = new DeadLockRunnable();
            deadLockRunnable1.num=1;
            DeadLockRunnable deadLockRunnable2 = new DeadLockRunnable();
            deadLockRunnable2.num=2;
            Thread thread = new Thread(deadLockRunnable1,"张三");
            Thread thread2 = new Thread(deadLockRunnable2,"李四");
            thread.start();
            try {
                Thread.currentThread().sleep(2000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            thread2.start();
        }
    }
    ```
    
    ### 重入锁
    
    重入锁是实现线程同步的另外一种方式,可以看作是synchronized的升级,synchronized是通过JVM实现的,重入锁是通过JDK实现的。
    
    重入锁的特点:
    
    可以给同一个资源添加多个锁,同时解锁的方式与synchronized也有不同,synchronized的锁是线程执行完毕之后自动释放,重入锁必须手动释放。
    
    可中断是指某个线程在等待获取锁的过程中可以主动终止线程,通过调用 lockInterruptibly() 方法来实现。
    
    重入锁还具备限时性的特点,指可以判断某个线程在一定的时间内能否获取锁,通过调用tryLock(long timeout,TimeUnit unit)方法来实现,其中timeout指时间数值,unit指时间单位,返回值是boolean,true 表示在该时间段内可以获取锁,false表示在该时间段内没有获取锁。
    
    ### 生产者消费者模式
    
    在一个生产环境中,生产者和消费者在同一个时间段内共享同一块缓冲区,生产者负责向缓冲区中添加数据,消费者负责从缓冲区中取出数据,以生产汉堡和消费汉堡为例来实现生产者消费者模式。
    
    ```java
    public class Hamburger {
        private int id;
    
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        @Override
        public String toString() {
            return "Hamburger [id=" + id + "]";
        }
        
        public Hamburger(int id) {
            this.id = id;
        }
    }
    ```
    
    ```java
    public class Container {
        public Hamburger[] array = new Hamburger[6];
        public int index = 0;
        //向容器中添加汉堡
        public synchronized void push(Hamburger hamburger) {
            while(index == array.length) {
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            this.notify();
            array[index] = hamburger;
            index++;
            System.out.println("生产了一个汉堡:"+hamburger);
        }
        //从容器中取出汉堡
        public synchronized Hamburger pop() {
            while(index == 0) {
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            this.notify();
            index--;
            System.out.println("消费了一个汉堡"+array[index]);
            return array[index];
        }
    }
    ```
    
    ```java
    public class Producer implements Runnable {
        private Container container = null;
        public Producer(Container container) {
            this.container = container;
        }
        @Override
        public void run() {
            // TODO Auto-generated method stub
            for(int i = 0; i < 30; i++) {
                Hamburger hamburger = new Hamburger(i);
                this.container.push(hamburger);
                try {
                    Thread.currentThread().sleep(1000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }
    ```
    
    ```java
    public class Consumer implements Runnable {
        private Container container = null;
        
        public Consumer(Container container) {
            this.container = container;
        }
    
        @Override
        public void run() {
            // TODO Auto-generated method stub
            for(int i = 0; i < 30; i++) {
                this.container.pop();
                try {
                    Thread.currentThread().sleep(1000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }
    ```
    
    ```java
    public class Test5 {
        public static void main(String[] args) {
            Container container = new Container();
            Producer producer = new Producer(container);
            Consumer consumer = new Consumer(container);
            new Thread(producer).start();
            new Thread(producer).start();
            new Thread(consumer).start();
            new Thread(consumer).start();
            new Thread(consumer).start();
        }
    }
    ```
    
    ### 练习
    
    火车站共有3个窗口出售火车票,共15张票,用多线程模拟3个窗口的售票情况。
    
    ```java
    
    public class TicketRunnable implements Runnable {
        //剩余的火车票
        public int scount = 15;
        //已售出的火车票
        public int ocount = 0;
    
        @Override
        public void run() {
            // TODO Auto-generated method stub
            while(scount>0) {
                try {
                    Thread.currentThread().sleep(1000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                if(scount == 0) {
                    return;
                }
                synchronized (TicketRunnable.class) {
                    scount--;
                    ocount++;
                    if(scount == 0) {
                        System.out.println(Thread.currentThread().getName()+"售出了第"+ocount+"张火车票,火车票已售完");
                    }else {
                        System.out.println(Thread.currentThread().getName()+"售出了第"+ocount+"张火车票,剩余"+scount+"张火车票");
                    }
                }
            }
        }
        
    }
    ```
    
    ```java
    public class Test6 {
        public static void main(String[] args) {
            TicketRunnable ticketRunnable = new TicketRunnable();
            new Thread(ticketRunnable,"窗口1").start();
            new Thread(ticketRunnable,"窗口2").start();
            new Thread(ticketRunnable,"窗口3").start();
        }
    }
    ```
    
    
    
    ### 集合框架
    
    集合可以理解为是一个长度可以改变,可以存放任意数据类型的动态数组。
    
    Collection            集合框架最基本的接口,存储一组无序、不唯一的对象
    
    List                    Collection的子接口,存储一组无序、不唯一的对象
    
    Set                    Collection的子接口,存储一组无序、唯一的对象
    
    Map                独立于Collection的另外一个接口,存储一组键值对象,提供键到值的映射
    
    Iterator                输出集合元素的接口,一般适用于无序集合,从前向后单向输出
    
    ListIterator            Iterator的子接口,可以双向输出集合中的元素
    
    Eummeration        传统的输出接口,已经被Irerator所取代

    Account.java

    import java.util.concurrent.locks.ReentrantLock;
    
    public class Account implements Runnable {
        private static int num;
        private ReentrantLock reentrantLock = new ReentrantLock();
        @Override
        public void run() {
            // TODO Auto-generated method stub
            reentrantLock.lock();
            reentrantLock.lock();
            num++;
            System.out.println(Thread.currentThread().getName()+"是当前的第"+num+"位访问");
            reentrantLock.unlock();
            reentrantLock.unlock();
        }
    
    }

    Chopsticks.java

    public class Chopsticks {
    
    }

    Consumer.java

    public class Consumer implements Runnable {
        private Container container = null;
        
        public Consumer(Container container) {
            this.container = container;
        }
    
        @Override
        public void run() {
            // TODO Auto-generated method stub
            for(int i = 0; i < 30; i++) {
                this.container.pop();
                try {
                    Thread.currentThread().sleep(1000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    
    }

    Container.java

    public class Container {
        public Hamburger[] array = new Hamburger[6];
        public int index = 0;
        //向容器中添加汉堡
        public synchronized void push(Hamburger hamburger) {
            while(index == array.length) {
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            this.notify();
            array[index] = hamburger;
            index++;
            System.out.println("生产了一个汉堡:"+hamburger);
        }
        //从容器中取出汉堡
        public synchronized Hamburger pop() {
            while(index == 0) {
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            this.notify();
            index--;
            System.out.println("消费了一个汉堡"+array[index]);
            return array[index];
        }
    }

    DeadLockRunnable.java

    public class DeadLockRunnable implements Runnable {
        
        public int num;
        private static Chopsticks chopsticks1 = new Chopsticks();
        private static Chopsticks chopsticks2 = new Chopsticks();
    
        @Override
        public void run() {
            // TODO Auto-generated method stub
            if(num == 1) {
                System.out.println(Thread.currentThread().getName()+"获取到chopsticks1,等待获取chopsticks2");
                synchronized (chopsticks1) {
                    try {
                        Thread.currentThread().sleep(100);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    synchronized (chopsticks2) {
                        System.out.println(Thread.currentThread().getName()+"用餐完毕");
                    }
                }
            }
            
            if(num == 2) {
                System.out.println(Thread.currentThread().getName()+"获取到chopsticks2,等待获取chopsticks1");
                synchronized (chopsticks2) {
                    try {
                        Thread.currentThread().sleep(100);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    synchronized (chopsticks1) {
                        System.out.println(Thread.currentThread().getName()+"用餐完毕");
                    }
                }
            }
            
        }
    
    }

    Hamburger.java

    public class Hamburger {
        private int id;
    
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        @Override
        public String toString() {
            return "Hamburger [id=" + id + "]";
        }
        
        public Hamburger(int id) {
            this.id = id;
        }
    }

    Producer.java

    public class Producer implements Runnable {
        private Container container = null;
        public Producer(Container container) {
            this.container = container;
        }
        @Override
        public void run() {
            // TODO Auto-generated method stub
            for(int i = 0; i < 30; i++) {
                Hamburger hamburger = new Hamburger(i);
                this.container.push(hamburger);
                try {
                    Thread.currentThread().sleep(1000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    
    }

    StopLock.java

    import java.util.concurrent.locks.ReentrantLock;
    
    public class StopLock implements Runnable{
        
        private ReentrantLock reentrantLock = new ReentrantLock();
    
        @Override
        public void run() {
            // TODO Auto-generated method stub
            try {
                reentrantLock.lockInterruptibly();
                System.out.println(Thread.currentThread().getName()+"get lock");
                Thread.currentThread().sleep(5000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }finally {
                reentrantLock.unlock();
            }
        }
    
    }

    Test.java

    public class Test {
        public static void main(String[] args) {
            DeadLockRunnable deadLockRunnable1 = new DeadLockRunnable();
            deadLockRunnable1.num=1;
            DeadLockRunnable deadLockRunnable2 = new DeadLockRunnable();
            deadLockRunnable2.num=2;
            Thread thread = new Thread(deadLockRunnable1,"张三");
            Thread thread2 = new Thread(deadLockRunnable2,"李四");
            thread.start();
            try {
                Thread.currentThread().sleep(2000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            thread2.start();
        }
    }

    Test2.java

    public class Test2 {
        public static void main(String[] args) {
            Account account = new Account();
            Thread thread1 = new Thread(account,"用户A");
            Thread thread2 = new Thread(account,"用户B");
            thread1.start();
            thread2.start();
        }
    }

    Test3.java

    public class Test3 {
        public static void main(String[] args) {
            StopLock stopLock = new StopLock();
            Thread thread1 = new Thread(stopLock,"线程1");
            Thread thread2 = new Thread(stopLock,"线程2");
            thread1.start();
            thread2.start();
            try {
                Thread.currentThread().sleep(1000);
                thread2.interrupt();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

    Test4.java

    public class Test4 {
        public static void main(String[] args) {
            TimeLock timeLock = new TimeLock();
            new Thread(timeLock,"线程1").start();
            new Thread(timeLock,"线程2").start();
        }
    }

    Test5.java

    public class Test5 {
        public static void main(String[] args) {
            Container container = new Container();
            Producer producer = new Producer(container);
            Consumer consumer = new Consumer(container);
            new Thread(producer).start();
            new Thread(producer).start();
            new Thread(consumer).start();
            new Thread(consumer).start();
            new Thread(consumer).start();
        }
    }

    Test6.java

    public class Test6 {
        public static void main(String[] args) {
            TicketRunnable ticketRunnable = new TicketRunnable();
            new Thread(ticketRunnable,"窗口1").start();
            new Thread(ticketRunnable,"窗口2").start();
            new Thread(ticketRunnable,"窗口3").start();
        }
    }

    TickerRunnable.java

    public class TicketRunnable implements Runnable {
        //剩余的火车票
        public int scount = 15;
        //已售出的火车票
        public int ocount = 0;
    
        @Override
        public void run() {
            // TODO Auto-generated method stub
            while(scount>0) {
                try {
                    Thread.currentThread().sleep(1000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                if(scount == 0) {
                    return;
                }
                synchronized (TicketRunnable.class) {
                    scount--;
                    ocount++;
                    if(scount == 0) {
                        System.out.println(Thread.currentThread().getName()+"售出了第"+ocount+"张火车票,火车票已售完");
                    }else {
                        System.out.println(Thread.currentThread().getName()+"售出了第"+ocount+"张火车票,剩余"+scount+"张火车票");
                    }
                }
            }
        }
        
    }

    TimeLock.java

    import java.util.concurrent.TimeUnit;
    import java.util.concurrent.locks.ReentrantLock;
    
    public class TimeLock implements Runnable {
        public ReentrantLock reentrantLock = new ReentrantLock();
        @Override
        public void run() {
            // TODO Auto-generated method stub
            try {
                if(reentrantLock.tryLock(6, TimeUnit.SECONDS)) {
                    System.out.println(Thread.currentThread().getName()+"get lock");
                    Thread.currentThread().sleep(5000);
                }else {
                    System.out.println(Thread.currentThread().getName()+"not lock");
                }
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } finally {
                if(reentrantLock.isHeldByCurrentThread()) {
                    reentrantLock.unlock();
                }
            }
        }
    
    }
  • 相关阅读:
    重构二叉树
    Nlog、elasticsearch、Kibana以及logstash
    技术
    Java 的垃圾回收机制(转)
    Java并发编程:并发容器之CopyOnWriteArrayList
    深入理解Arrays.sort() (转)
    浅析java的浅拷贝和深拷贝
    gradle
    @action 注解
    如何使用mysql
  • 原文地址:https://www.cnblogs.com/HiJackykun/p/11172903.html
Copyright © 2011-2022 走看看