Java多线程设计模式-序章1Java多线程

96 阅读3分钟

1、线程的启动

  1. 利用Thread的子类

    /**
     * Thread的子类
     */
    public class MyThread extends Thread {
        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {
                System.out.println(i);
            }
        }
    }
    /**
     * 通过Thread子类的start的方法启动一个线程
     */
    public class Main {
        public static void main(String[] args) {
            MyThread myThread = new MyThread();
            myThread.start();
        }
    }
    
  2. 利用runnable接口

    /**
     * 实现Runnable接口
     */
    public class MyRunnable implements Runnable {
        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {
                System.out.println(i);
            }
        }
    }
    /**
     * 创建Runnable的实现类,将实现类的实例作为参数传给Thread的构造方法,调用start方法启动线程
     */
    public class Main {
        public static void main(String[] args) {
            MyRunnable myRunnable = new MyRunnable();
            Thread thread = new Thread(myRunnable);
            thread.start();
        }
    }
    

总结:以上两种方法最终都是使用的Thread类的start方法启动线程的。

2、线程的暂停

  1. 通过调用sleep方法暂停线程。

    public class Main {
        public static void main(String[] args) {
            try {
                Thread.sleep(300000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    

3、线程互斥处理

  1. synchronized方法:如果一个方法前面加上关键词synchronized,那么这个方法每次只能由一个方法运行。这种方法称为同步方法。synchronized静态方法使用该类的类对象Class作为锁来执行线程互斥的。
  2. synchronized代码块。

总结:线程的互斥机制称为监视,获取锁也称为拥有监视或者持有锁。可以通过Thread.holdLock方法来确认线程是否以获取某个锁。

public class Main {
    public static void main(String[] args) {
      Thread.holdsLock(Main.class)
    }
}

4、线程的协作

  1. Java提供waitnotifynotifyAll来控制线程。wait方法线程等待,notifynotifyAll方法用来唤醒阻塞的线程。上述的几个方法都来自于Object类。这个方法必须在持有锁的时候调用,也就是必须在synchronized代码块中调用,否则会抛出java.lang.IllegalMonitorStateException异常。

  2. 等待队列

    所有的实例都有一个等待队列,这个等待队列是在线程调用实例的wait方法之后将当前线程放入这个等待队里中。当以下任意一种情况发生时,线程便会退出等待队里。

    1. 有其他线程的notify方法来唤醒线程
    2. 有其他线程的notifyAll方法来唤醒线程
    3. 有其他线程的interrupt方法来唤醒线程
    4. wait方法超时

3、wait方法

wait方法j将会使线程进入等待队列

public void test() throws InterruptedException {
    Object object = new Object();
    synchronized (object) {
        //调用wait方法,使当前线程进入object实现的等待队列中
        object.wait();
    }
}
  1. notify方法

notify方法将会从等待队列中唤醒一个线程。notify唤醒的线程病不会在执行notify的一瞬间重新运行。因为在那一瞬间执行notify的的线程还持有者锁,所以其他线程无法获取到这个锁的实例。

  1. notifyAll方法

notify类似,只不过notifyAll唤醒了所有等待的线程。

5、线程状态的迁移

线程状态枚举

 public enum State {
        /**
         * 线程刚被new出来,没有调用过start方法
         */
        NEW,
​
        /**
         * 线程调用了start方法,变为了可运行状态,等待系统的调度
         */
        RUNNABLE,
​
        /**
         * 线程等待锁被阻塞
         */
        BLOCKED,
​
        /**
         * 线程等待另一个线程执行某个动作
         */
        WAITING,
​
        /**
         * 
         */
        TIMED_WAITING,
​
        /**
         * run方法结束
         */
        TERMINATED;
    }

线程状态转换图.jpg