Talk is cheap.Show your code
林怼怼~~
就突然想到,程序员的粉丝都是程序员,当一个程序员看另一个程序员的代码时...嗯,你懂得
升级版怼怼
前言
--本篇内容整理线程相关知识复习巩固,属于三刷,
--解决windows下无法安装linux命令给git打差异包的问题
1.创建线程的方法?
有且仅有一个本质上就是new Thread(),至于runnable,callable,还是线程池ThreadPoolExecutor都是对调用run方法的一个扩展。
2.如何创建一个进程
public static void main(String[] args) throws InterruptedException, IOException { Runtime runtime = Runtime.getRuntime(); Process exec = runtime.exec("cmd /k http://www.baidu.com"); exec.exitValue(); }
3.如何销毁一个线程?
java无法销毁一个线程,只能改变线程状态
当线程异常时,可视为中断销毁
但当thread.Alive返回false时已经被销毁
4.如何通过java API启动线程?
thread.start()
5.如何实现线程顺序打印?
方法1 join start
private static void threadJoinOneByOne() throws InterruptedException { Thread t1 = new Thread(ThreadExecutionQuestion::action, "t1"); Thread t2 = new Thread(ThreadExecutionQuestion::action, "t2"); Thread t3 = new Thread(ThreadExecutionQuestion::action, "t3"); // start() 仅是通知线程启动 t1.start(); // join() 控制线程必须执行完成 t1.join();
t2.start(); t2.join();
t3.start(); t3.join(); }
方法2 isAlive自旋
private static void threadLoop() {
Thread t1 = new Thread(ThreadExecutionQuestion::action, "t1"); Thread t2 = new Thread(ThreadExecutionQuestion::action, "t2"); Thread t3 = new Thread(ThreadExecutionQuestion::action, "t3");
t1.start();
while (t1.isAlive()) { // 自旋 Spin }
t2.start();
while (t2.isAlive()) {
}
t3.start();
while (t3.isAlive()) {
}
}
方法3 方法2+sleep
private static void threadSleep() throws InterruptedException {
Thread t1 = new Thread(ThreadExecutionQuestion::action, "t1"); Thread t2 = new Thread(ThreadExecutionQuestion::action, "t2"); Thread t3 = new Thread(ThreadExecutionQuestion::action, "t3");
t1.start();
while (t1.isAlive()) { // sleep Thread.sleep(0); }
t2.start();
while (t2.isAlive()) { Thread.sleep(0); }
t3.start();
while (t3.isAlive()) { Thread.sleep(0); }
}
方法4 join的实现
先判断线程状态没然后调用wait方法通知thread
private static void threadStartAndWait(Thread thread) {
if (Thread.State.NEW.equals(thread.getState())) { thread.start(); } while (thread.isAlive()) { synchronized (thread) { try { thread.wait(); } catch (Exception e) { throw new RuntimeException(e); } } } }
其他实现countdownLatch,cyclicbarrier都是可以的
6.如何停止一个线程
开关法,
public class HowToStopThreadQuestion {
public static void main(String[] args) throws InterruptedException {
Action action = new Action();
// 子线程 Thread t1 = new Thread(action, "t1");
t1.start();
// 改变 action stopped 状态 action.setStopped(true);
t1.join();
Thread t2 = new Thread(() -> { if (!Thread.currentThread().isInterrupted()) { action(); } }, "t2");
t2.start(); // 中断操作(仅仅设置状态,而并非中止线程) t2.interrupt(); t2.join(); }
private static class Action implements Runnable {
// 线程安全问题,确保可见性(Happens-Before) private volatile boolean stopped = false;
@Override public void run() { if (!stopped) { // 执行动作 action(); } }
public void setStopped(boolean stopped) { this.stopped = stopped; } }
private static void action() { System.out.printf("线程[%s] 正在执行...\n", Thread.currentThread().getName()); // 2 }}
7为什么java要放弃stop方法
防止死锁
8.说明Thread interrupt,isinterrupted,interrupted 的区别和含义
Thread.interrupt() 设置状态
isInterrupted() 判断 返回Boolean
interrupted 即判断又清除
9.线程异常会发生什么?
发生异常时,isAlive会返回false,线程中断或销毁
10.如何捕获线程异常?
Thread.setDefaultUncaughtExceptionHandler源码
public static void setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler eh) { SecurityManager sm = System.getSecurityManager(); if (sm != null) { sm.checkPermission( new RuntimePermission("setDefaultUncaughtExceptionHandler") ); }
defaultUncaughtExceptionHandler = eh; }
public class ThreadExceptionQuestion {
public static void main(String[] args) throws InterruptedException {
Thread.setDefaultUncaughtExceptionHandler((thread, throwable) -> { System.out.printf("线程[%s] 遇到了异常,详细信息:%s\n", thread.getName(), throwable.getMessage()); });
// main 线程 -> 子线程 Thread t1 = new Thread(() -> { throw new RuntimeException("数据达到阈值"); }, "t1");
t1.start(); // main 线程会中止吗? t1.join();
// Java Thread 是一个包装,它由 GC 做垃圾回收 // JVM Thread 可能是一个 OS Thread,JVM 管理, // 当线程执行完毕(正常或者异常) System.out.println(t1.isAlive()); }}
Connected to the target VM, address: '127.0.0.1:49192', transport: 'socket'线程[t1] 遇到了异常,详细信息:数据达到阈值falseDisconnected from the target VM, address: '127.0.0.1:49192', transport: 'socket'
捕捉到线程异常,避免线程并发异常堆栈溢出
插播【git clone 报错】解决方法
penSSL SSL_read: Connection was reset, errno 10054
在git clone vuex 项目时报错
是服务器的SSL证书没有经过第三方机构的签署,所以报错。解决办法:git config --global http.sslVerify "false"
11.当遇到异常时,线程池如何捕捉?
afterExecute方法
public static void main(String[] args) throws InterruptedException {
// ExecutorService executorService = Executors.newFixedThreadPool(2);
ThreadPoolExecutor executorService = new ThreadPoolExecutor( 1, 1, 0, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>() ) {
/** * 通过覆盖 {@link ThreadPoolExecutor#afterExecute(Runnable, Throwable)} 达到获取异常的信息 * @param r * @param t */ @Override protected void afterExecute(Runnable r, Throwable t) { System.out.printf("线程[%s] 遇到了异常,详细信息:%s\n", Thread.currentThread().getName(), t.getMessage()); }
};
executorService.execute(() -> { throw new RuntimeException("数据达到阈值"); });
// 等待一秒钟,确保提交的任务完成 executorService.awaitTermination(1, TimeUnit.SECONDS);
// 关闭线程池 executorService.shutdown();
}
git diff windows解决无法用命令打差异包的问题。
git diff hotfix/0417 55ebcf7f6 --name-only --diff-filter=ACMR | xargs zip cloud.zip
试过很多方法去解决这个打差异包的问题,为了找出发版之间的增量代码,Windows下安装过http://www.cygwin.com/但无济于事
git小乌龟~Tortoisegit
在项目根路径右键
Diff with previous version
然后比较并去掉配置文件等导出,导出后打包~
本文内容根据B站UP主mercyblitz,2019.4.07期视频以及历史资料整理,扫描二维码关注小马哥公众号,java劝退师,好东西需要分享,干货满满
- 点赞
- 收藏
- 关注作者
评论(0)