前言:Java线程的实现方式有3种,分别是 Thread,Runable,Callable。
1.Thread
/** * 线程死锁 用jstack pid查看死锁 * @author wangting * */ public class DeadLock extends Thread { protected Object tool; static Object fork1 = new Object(); static Object fork2 = new Object(); public DeadLock(Object tool) { this.tool = tool; if (tool == fork1) { this.setName("哲学家A"); } if (tool == fork2) { this.setName("哲学家B"); } } @Override public void run() { if(tool == fork1){ synchronized (fork1) { try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (fork2) { System.out.println("哲学家A开始吃饭了"); } } } if(tool == fork2){ synchronized (fork2) { try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (fork1) { System.out.println("哲学家B开始吃饭了"); } } } } public static void main(String[] args) throws InterruptedException { DeadLock A = new DeadLock(fork1); DeadLock B = new DeadLock(fork2); A.start(); B.start(); Thread.sleep(1000); } }
输出:
最终毫无输出,原因死锁。
用jstack pid 可以查看到死锁日志:
Found one Java-level deadlock:
=============================
"哲学家B":
waiting to lock monitor 0x0000000002e16c48 (object 0x00000000d6063518, a java.lang.Object),
which is held by "哲学家A"
"哲学家A":
waiting to lock monitor 0x00000000191adfb8 (object 0x00000000d6063528, a java.lang.Object),
which is held by "哲学家B"
Java stack information for the threads listed above:
===================================================
"哲学家B":
at com.java.concurrent.thread.DeadLock.run(DeadLock.java:45)
- waiting to lock <0x00000000d6063518> (a java.lang.Object)
- locked <0x00000000d6063528> (a java.lang.Object)
"哲学家A":
at com.java.concurrent.thread.DeadLock.run(DeadLock.java:33)
- waiting to lock <0x00000000d6063528> (a java.lang.Object)
- locked <0x00000000d6063518> (a java.lang.Object)
Found 1 deadlock.
2. Runable
/** * 线程中断 * @author wt * */ public class ThreadInterrupt implements Runnable { public void run() { try { System.out.println("in run() - about to work2()"); work(); System.out.println("in run() - back from work2()"); } catch (InterruptedException x) { System.out.println("in run() - interrupted in work2()"); return; } System.out.println("in run() - doing stuff after nap"); System.out.println("in run() - leaving normally"); } public void work() throws InterruptedException { while (true) { if (Thread.currentThread().isInterrupted()) { System.out.println("C isInterrupted()=" + Thread.currentThread().isInterrupted()); Thread.sleep(1); System.out.println("D isInterrupted()=" + Thread.currentThread().isInterrupted()); } } } public static void main(String[] args) { ThreadInterrupt si = new ThreadInterrupt(); Thread t = new Thread(si); t.start(); try { Thread.sleep(1000); } catch (InterruptedException x) { } System.out.println("in main() - interrupting other thread"); t.interrupt(); System.out.println("in main() - leaving"); } }
输出:
in run() - about to work2()
in main() - interrupting other thread
in main() - leaving
C isInterrupted()=true
in run() - interrupted in work2()
理由:
thread.interrupt 函数是线程中断的含义。一个线程在运行状态中,其中断标志被设置为true,则此后,一旦线程调用了wait、jion、sleep方法中的一种,立马抛出一个InterruptedException,且中断标志被清除,重新设置为false。
3.Callable
/** * Callable举例 * @author wt * */ public class CallableExample { public static void main(String[] args) { Callable<Integer> callable = new Callable<Integer>() { public Integer call() throws Exception { Thread.sleep(1000);// 可能做一些事情 return new Random().nextInt(100); } }; FutureTask<Integer> future = new FutureTask<Integer>(callable); new Thread(future).start(); try { System.out.println(future.get()); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } } }
输出:
`一个数字`
理由:
Callable是个泛型参数化接口,并能返回线程的执行结果,且能在无法正常计算时抛出异常
4.其他例子:
/** * Created by wt on 2017/11/7. */ public class SearchFutureTask { private static String[] s = { "abcdeaf", "vgqqssaa", "cfwqaadfw" }; public static void main(String[] args) throws ExecutionException, InterruptedException { int count = 0; ArrayList<Future<Integer>> rs = new ArrayList<>(); for (String s0 : s) { MatchCount mc1 = new MatchCount("a", s0); FutureTask<Integer> task = new FutureTask<>(mc1); rs.add(task); Thread thread = new Thread(task); thread.start(); } for (Future<Integer> f : rs) { count += f.get(); // 迭代返回结果并累加 } System.out.println("包含关键字的总数为:" + count); } public static class MatchCount implements Callable<Integer> { public String keyword; private String str; private Integer count = 0; public MatchCount() { } public MatchCount(String keyword, String str) { this.keyword = keyword; this.str = str; } public Integer call() throws Exception { search(str, keyword); return count; } public void search(String str, String keyword) { for (int index = 0; index < str.length(); index++) { if(str.substring(index, index+1).equals(keyword)){ count++; } } } } }
输出结果:
包含关键字的总数为:6