创建线程的方式
1. Thread
public static void main(String[] args) {
Thread thread = new CusThread();
thread.start();
}
public static class CusThread extends Thread{
@Override
public void run() {
System.out.println("CusThread run ");
}
}
-
start()
与run()
区别
start
是启动线程,start
是用synchronized
修饰的,无法多次调用
run
是运行方法,可以多次调用
public synchronized void start() {}
-
stop()
:停止,不安全,不建议使用,用interrupt
替代,stop
不会抛出异常 -
suspend()
:暂停,不安全,不建议使用 -
resume()
:重新开始 -
interrupt()
:只是一个标记,需要线程自己来终止,需要处理抛出的异常
Thread.interrupt()
,静态方法会清楚标记
Thread.currentThread().isInterrupt()
,实例化方法不会清除标记 -
join()
:等待某个线程执行完毕再继续
打印:public static void main(String[] args) { Thread thread1 = new Thread(()->{ System.out.println("thread1 start"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("thread1"); System.out.println("thread1 end"); },"1"); Thread thread2 = new Thread(()->{ System.out.println("thread2 start"); try { Thread.sleep(1000); thread1.join(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("thread2"); System.out.println("thread2 end"); },"2"); Thread thread3 = new Thread(()->{ System.out.println("thread3 start"); try { Thread.sleep(1000); thread2.join(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("thread3"); System.out.println("thread3 end"); },"3"); System.out.println("thread will start"); thread1.start(); thread2.start(); thread3.start(); try { thread3.join(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("thread did start end"); }
thread will start thread will start thread1 start thread2 start thread3 start thread1 thread1 end thread2 thread2 end thread3 thread3 end thread did start end
-
sleep()
:睡眠 -
wait()
:睡眠,其他线程会加入,与synchronized
结合使用 -
notify()
:唤醒当前睡眠线程,与synchronized
结合使用 -
notifyAll()
:唤醒所有睡眠线程
thread1
启动后wait
,thread2
唤醒thread1
打印:public class CusThread01 { private static String lock = "lock"; public static void main(String[] args) { Thread thread1 = new Thread(()->{ synchronized (lock) { System.out.println("thread1 start"); try { Thread.sleep(1000); lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("thread1 end"); } },"1"); thread1.start(); new Thread(()->{ synchronized(lock){ System.out.println("thread2 start"); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } lock.notifyAll(); System.out.println("thread2 end"); } },"2").start(); } }
thread1 start thread2 start thread2 end thread1 end
2. Runnable
public static void main(String[] args) {
CusRunnable cusRunnable = new CusRunnable();
Thread thread = new Thread(cusRunnable);
thread.start();
}
public static class CusRunnable implements Runnable{
@Override
public void run() {
System.out.println("CusRunnable run ");
}
}
3. Callable
public static void main(String[] args) {
CusCallable cusCallable = new CusCallable();
FutureTask<String> futureTask = new FutureTask<>(cusCallable);
Thread t = new Thread(futureTask);
t.start();
try {
String res = futureTask.get();
System.out.println("CusCallable res: " + res);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
public static class CusCallable implements Callable<String> {
@Override
public String call() throws Exception {
return "CusThread.call run";
}
}
4. 匿名内部类
new Thread(){
@Override
public void run() {
System.out.println("1111");
}
}.start();
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("2222");
}
}).start();
5. Lambda
new Thread(()-> System.out.println("111")).start();
6. 定时器
Timer timer = new Timer();
//每隔1s执行一次
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
System.out.println("123445");
}
},0/**延迟*/,1000/**间隔*/);
7. 线程池
ExecutorService executorService = Executors.newSingleThreadExecutor();
executorService.execute(new Runnable() {
@Override
public void run() {
System.out.println("1234");
}
});
executorService.execute(()->{
System.out.println("4321");
});
![](https://img.haomeiwen.com/i1621313/71051a9ad4983a46.png)
线程池
public ThreadPoolExecutor(int corePoolSize, //核心线程池大小
int maximumPoolSize, // 最大线程池大小
long keepAliveTime, // 线程最大空闲时间
TimeUnit unit, // 时间单位
BlockingQueue<Runnable> workQueue, // 线程等待队列
ThreadFactory threadFactory, // 线程创建工厂
RejectedExecutionHandler handler ) { //拒绝策略
-
拒绝策略:
AbortPolicy
:默认策略,抛出RejectedExecutionException
异常
CallerRunsPolicy
:这提供了一个简单的反馈控制机制,可以减慢提交新任务的速度;
DiscardPolicy
:直接丢弃新提交的任务;
DiscardOldestPolicy
:如果执行器没有关闭,队列头的任务将会被丢弃,然后执行器重新尝试执行任务(如果失败,则重复这一过程); -
预定义线程池
FixedThreadPool
public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); }
corePoolSize=maximumPoolSize
,线程都是核心线程,是一个固定大小的线程池
keepAliveTime
对核心线程无效,FixedThreadPool
中全部都是核心线程
workQueue
是LinkedBlockingQueue
无界阻塞队列,队列最大值为Integer.MAX_VALUE
,所以任务添加>消耗,可能会内存溢出。
FixedThreadPool
执行是无序的
用途:用于web服务瞬时削峰,不会长时间高峰运行。 -
直接握手队列
CachedThreadPool
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
corePoolSize =0
,maximumPoolSize=Integer.MAX_VALUE
,线程无限制
KeepAliveTime=60s
,线程空闲时间为60s
workQueue
是SynchronousQueue
同步队列,SynchronousQueue
不会有队列等待
用途:快速处理大量耗时短的任务,如:Netty的NIO接受请求
- 单线程处理
SingleThreadExecutor
public static ExecutorService newSingleThreadExecutor() { return new FinalizableDelegatedExecutorService (new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>())); }
Executors.newFixedThreadPool(1)
这种单线程可以修改其corePoolSize
,使其非单线程
-
周期性调用
ScheduledThreadPool
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) { return new ScheduledThreadPoolExecutor(corePoolSize); }
ScheduledthreadPool extend ThreadPoolExecutor
与Timer对比- Timer 单线程 任务之间互相影响 绝对时间 单任务异常,后续任务受影响
- ScheduledThreadPoolExecutor 多线程 任务之间互不影响 相对时间 无影响
// 特定时间延时后执行一次Runnable public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit); // 特定时间延时后执行一次Callable public <V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit); // 固定周期执行任务(与任务执行时间无关,周期是固定的) public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit); // 固定延时执行任务(与任务执行时间有关,延时从上一次任务完成后开始) public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit);
-
关闭线程池
- 当线程池执行shutdown时再调用线程池方法会执行拒绝策略
public static void main(String[] args) { ThreadPoolExecutor executor = new ThreadPoolExecutor(4, 4, 10, TimeUnit.SECONDS, new LinkedBlockingQueue<>()); executor.execute(() -> System.out.println("before shutdown")); executor.shutdown(); executor.execute(() -> System.out.println("after shutdown")); }
- 等待队列中有100个任务,执行task0后立即shutdown,并不会停止接下来的100个任务
public class WaitqueueTest { public static void main(String[] args) { BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>(); for(int i = 1; i <= 100 ; i++){ workQueue.add(new Task(String.valueOf(i))); } ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1, 10, TimeUnit.SECONDS, workQueue); executor.execute(new Task("0")); executor.shutdown(); System.out.println("workQueue size = " + workQueue.size() + " after shutdown"); } static class Task implements Runnable{ String name; public Task(String name) { this.name = name; } @Override public void run() { for(int i = 1; i <= 10; i++){ System.out.println("task " + name + " is running"); } System.out.println("task " + name + " is over"); } } }
- 队列中有100个任务,执行task0立即shutdownNow,task0执行完毕,其他的停止
public class WaitqueueTest { public static void main(String[] args) { BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>(); for(int i = 1; i <= 100 ; i++){ workQueue.add(new Task(String.valueOf(i))); } ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1, 10, TimeUnit.SECONDS, workQueue); executor.execute(new Task("0")); // shutdownNow有返回值,返回被抛弃的任务list List<Runnable> dropList = executor.shutdownNow(); System.out.println("workQueue size = " + workQueue.size() + " after shutdown"); System.out.println("dropList size = " + dropList.size()); } static class Task implements Runnable{ String name; public Task(String name) { this.name = name; } @Override public void run() { for(int i = 1; i <= 10; i++){ System.out.println("task " + name + " is running"); } System.out.println("task " + name + " is over"); } } }
- 通过
interrupt
来停止线程
public static void main(String[] args) throws InterruptedException { ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1, 10, TimeUnit.SECONDS, new LinkedBlockingQueue<>()); executor.execute(new Task("0")); Thread.sleep(1); executor.shutdownNow(); System.out.println("executor has been shutdown"); } static class Task implements Runnable { String name; public Task(String name) { this.name = name; } @Override public void run() { for (int i = 1; i <= 100 ; i++) { if (!Thread.currentThread().isInterrupted()){ Thread.yield(); System.out.println("task " + name + " is running, round " + i); } else { System.out.println("stop"); break; } } } }
网友评论