原创转载请注明出处:https://www.cnblogs.com/agilestyle/p/11426916.html
Note:
Callable接口和Runnable接口区别
类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是随机唤醒一个等待某个资源的线程,进入就绪队列等待CPU的调度
notifyAll是唤醒所有的,进入就绪队列等待CPU调度
sleep方法是在指定的时间内让正在执行的线程暂停执行,但不会释放锁。
wait方法是让当前线程等待,直到其他线程调用对象的notify或notifyAll方法。wait方法会释放掉锁,使别的线程有机会占用锁。
Java线程类型:
守护线程是一种特殊的线程,当进程中不存在非守护线程了,则守护线程自动销毁。
Daemon的作用是为其他线程的运行提供便利服务,守护线程最典型的引用就是GC。
同步和互斥,等待/通知机制
可以使用synchronized/wait/notify/notifyAll,Lock/Condition, Semaphore/CountDownLatch/CyclicBarrier/Phaser
通过为每个线程提供一个独立的变量副本解决了变量并发访问的冲突问题
概括起来说,对于多线程资源共享的问题,同步机制采用了“以时间换空间”的方式,比如定义一个static变量,同步访问 —— 数据共享,而ThreadLocal采用了“以空间换时间”的方式 —— 数据隔离。前者仅提供一份变量,让不同的线程排队访问,而后者为每一个线程都提供了一份变量,因此可以同时访问而互不影响。
原文:https://www.cnblogs.com/agilestyle/p/11426916.html