JAVA多线程系列--线程实现方式

前言: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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值