进程:具有一定独立功能的程序关于某个数据集合上的一次运行活动,是系统进行资源分配和调度的一个独立单位
线程:进程的一个实体,是cpu分配调度的基本单位,代码的执行体。
线程的状态图
创建并使用线程
- 学习方法:通过阅读jdk的Thread类注释
- 线程的创建和使用
- 实现thread & runnable
- 误区: start not run
- 线程名字
- 通过Callable和Future创建和使用线程
public class ThreadTest {
public static void main(String[] args){
PrimeThread thread = new PrimeThread();
thread.setName("runnable");
thread.start();
Runnable runnable = () -> System.out.println(Thread.currentThread().getName() +
" runnable run");
Thread t = new Thread(runnable);
t.start();
t.run(); //main
System.out.println(Thread.currentThread().getName());
}
static class PrimeThread extends Thread{
@Override
public void run(){
System.out.println(Thread.currentThread().getName() + " Thread run");
}
}
}
线程协作
- 线程不被分配资源,资源在进程中,资源是共享的
- 关键字synchronized
- 临界区
- 锁
package thread;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* 示例:售票
*/
public class Tickets {
int tickets = 10;
/**
* 重复售票
*/
// void sell(){
// while(tickets > 0){
// System.out.println(Thread.currentThread().getName() + " sell ticket:" + tickets);
// tickets--;
// }
// System.out.println(Thread.currentThread().getName() + " sell out.");
// }
/**
* sync之后,导致独占资源
*/
// synchronized void sell(){
// while(tickets > 0){
// System.out.println(Thread.currentThread().getName() + " sell ticket:" + tickets);
// tickets--;
// }
// System.out.println(Thread.currentThread().getName() + " sell out.");
// }
/**
* 改善后,资源没有独占
*/
// void sell(){
// while(tickets > 0){
// synchronized (Tickets.class) {
// System.out.println(Thread.currentThread().getName() + " sell ticket:" + tickets);
// tickets--;
// }
// }
// //do something
// try{
// TimeUnit.MILLISECONDS.sleep(50L);
// } catch(InterruptedException e){
// e.printStackTrace();
// }
// System.out.println(Thread.currentThread().getName() + " sell out.");
// }
/**
* 改善后,资源没有独占,修复卖出无效票的问题
*/
// void sell(){
// while(tickets > 0){
// synchronized (this) {
// if(tickets > 0) {
// System.out.println(Thread.currentThread().getName() + " sell ticket:" + tickets);
// tickets--;
// }
// }
// }
// //do something
// try{
// TimeUnit.MILLISECONDS.sleep(50L);
// } catch(InterruptedException e){
// e.printStackTrace();
// }
// System.out.println(Thread.currentThread().getName() + " sell out.");
// }
private Lock lock = new ReentrantLock();
/**
* 使用锁
*/
void sell(){
while(tickets > 0){
lock.lock();
try{
if(tickets > 0) {
System.out.println(Thread.currentThread().getName() + " sell ticket:" + tickets);
tickets--;
}
}finally {
lock.unlock(); //锁必须在finally块中释放
}
}
//do something
try{
TimeUnit.MILLISECONDS.sleep(50L);
} catch(InterruptedException e){
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " sell out.");
}
public static void main(String[] args){
Tickets tickets = new Tickets();
Thread sellerA = new Thread(tickets::sell);
sellerA.setName("sellerA");
Thread sellerB = new Thread(tickets::sell);
sellerB.setName("sellerB");
Thread sellerC = new Thread(tickets::sell);
sellerC.setName("sellerC");
sellerA.start();
sellerB.start();
sellerC.start();
}
}
线程池
- 池:资源池、连接池、线程池
- 线程开销与线程复用
- 线程池的作用
- 线程池的基本原理
线程池的使用:
- 线程池的构造
- java包中预置的线程池
- java包中预置的线程池的Bug
package thread;
import java.util.concurrent.*;
public class ThreadPool {
public static void main(String[] args){
/**
* public ThreadExecutor(int corePoolSize,
* int maximumPoolSize,
* long keepAliveTime,
* TimeUnit unit,
* BlockingQueue<Runnable> workQueue,
* ThreadFactory threadFactory,
* RejectedExecutionHandler handler){
* handler: DiscardPolicy, AbortPolicy, callerRunPolicy, DiscardOldestPolicy
*/
ThreadPoolExecutor threadPoolExecutor =
new ThreadPoolExecutor(16, 30, 30L, TimeUnit.SECONDS,
new ArrayBlockingQueue<Runnable>(10), new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread();
t.setDaemon(false);
t.setUncaughtExceptionHandler((thread, e) -> System.out.println(e.getMessage()));
return t;
}
}, new ThreadPoolExecutor.DiscardOldestPolicy());
threadPoolExecutor.submit(() -> System.out.println(Thread.currentThread().getName()));
threadPoolExecutor.shutdown();
// ExecutorService executorService = Executors.newFixedThreadPool();
findJavaExecutorsBug();
}
/**
* java预置线程池
* Executors.newSingleThreadExecutor
* Executors.newCachedThreadPool
* Executors.newFixedThreadPool
* Executors.newScheduledThreadPool
* 暴力发现bug。运行时设置jvm启动参数 -Xmx10m。 限定jvm可使用的最大内存。
*/
static void findJavaExecutorsBug(){
ExecutorService executorService = Executors.newSingleThreadExecutor();
for(;;){
executorService.submit(() -> {
try{
TimeUnit.SECONDS.sleep(30);
} catch (InterruptedException e){
e.printStackTrace();
}
});
}
}
}