Concurrent - 多线程
原创转载请注明出处:https://www.cnblogs.com/agilestyle/p/11426916.html
Java中有几种方法可以实现一个线程?
- 继承Thread类(不支持多继承)
- 实现Runnable接口
- 实现Callable接口
- 线程池ThreadPoolExecutor
Note:
Callable接口和Runnable接口区别
- Callable接口的call()方法可以返回值,而Runnable接口的run()方法没有返回值
- Callable接口的call()方法可以声明抛出异常,而Runnable接口的run()方法不可以声明抛出异常
类ThreadPoolExecutor可以非常方便地创建线程池对象,而不需要程序员设计大量的new实例化Thread相关的代码
如何停止一个正在运行的线程?
使用flag,使线程正常退出,也就是当run方法完成后线程终止
1 package org.fool.java.concurrent.thread; 2 3 public class ThreadFlagTest { 4 public static void main(String[] args) throws InterruptedException { 5 MyThread myThread = new MyThread(); 6 7 Thread t1 = new Thread(myThread); 8 t1.start(); 9 10 Thread.sleep(1000); 11 12 myThread.stop(); 13 } 14 15 public static class MyThread implements Runnable { 16 private volatile boolean flag = true; 17 18 public void stop() { 19 flag = false; 20 } 21 22 @Override 23 public void run() { 24 while (flag) { 25 System.out.println(Thread.currentThread().getName() + System.currentTimeMillis()); 26 } 27 } 28 } 29 }
使用stop方法强行终止线程(不推荐,deprecated)
使用interrupt方法中断线程(调用interrupt方法仅仅是在当前线程中打了一个停止的flag,并不是真正的停止线程)
Note:
Why Are Thread.stop, Thread.suspend, Thread.resume and Runtime.runFinalizersOnExit Deprecated?
notify()和notifyAll()有什么区别?
notify是随机唤醒一个等待某个资源的线程,进入就绪队列等待CPU的调度
notifyAll是唤醒所有的,进入就绪队列等待CPU调度
sleep()和 wait()有什么区别?
sleep方法是在指定的时间内让正在执行的线程暂停执行,但不会释放锁。
wait方法是让当前线程等待,直到其他线程调用对象的notify或notifyAll方法。wait方法会释放掉锁,使别的线程有机会占用锁。
什么是Daemon线程?它有什么意义?
Java线程类型:
- 用户线程
- 守护线程
守护线程是一种特殊的线程,当进程中不存在非守护线程了,则守护线程自动销毁。
Daemon的作用是为其他线程的运行提供便利服务,守护线程最典型的引用就是GC。
Java如何实现多线程之间的通讯和协作?
同步和互斥,等待/通知机制
可以使用synchronized/wait/notify/notifyAll,Lock/Condition, Semaphore/CountDownLatch/CyclicBarrier/Phaser
ThreadLocal作用?
通过为每个线程提供一个独立的变量副本解决了变量并发访问的冲突问题
概括起来说,对于多线程资源共享的问题,同步机制采用了“以时间换空间”的方式,比如定义一个static变量,同步访问 —— 数据共享,而ThreadLocal采用了“以空间换时间”的方式 —— 数据隔离。前者仅提供一份变量,让不同的线程排队访问,而后者为每一个线程都提供了一份变量,因此可以同时访问而互不影响。