星空网 > 软件开发 > Java

Java中线程总结

本文简要介绍在 Java 世界中, 线程相关知识。主要包含 线程的创建与销毁;线程安全与同步;线程通讯;注意本文没有什么高深新知识,只缘起前段时间在翻看项目代码的时候,发现有些同学对此有诸多误解,故在此稍微整理一下,以帮助类似同学,同时警醒一下自己。

1.  线程的创建和销毁;

a) .创建线程可以通过继承 Thread 类 或 实现 Runnable 接口, 并重写 run() 方法, 其中的run() 方法即是本线程需要执行的内容.

b). 相比于单独继承 Thread ,Runnable接口配合 Thread 实现会更灵活,并可以通过共享一个Runnable接口实例,在Thread**享资源.

c). 至于线程销毁,不推荐使用 Thread.Stop()方法, 此方法在使用不当情况下会出现死锁,更多的时候推荐在run()方法中使用额外变量(或条件)结束此方法即可.

 2. 线程安全与同步;

a). 对于需要遵循ACID原子一致性的代码段, 可以通过 synchronized(lockKey){} 代码块锁定;

b). 同时 synchronized 关键字可以用来修饰一个方法,表示整个方法都需要遵循ACID原子一致性,值得注意的是,此时其实的lockKey等效于this关键字;

b). 在锁定的代码块中推荐再进行一次必要的条件判断。

  3. 线程通讯,在java的世界中可以借助 wait() notify() notifyAll() 这三个方法来完成,这三个方法定义在Object类中,因此所有的对象都可以使用.

  4.下面通过简单的几个代码片段来加以说明

  a). 演示线程创建与销毁,及线程安全与同步

 

Java中线程总结Java中线程总结
 1 public class ThreadTest implements Runnable { 2   private boolean stop;          //是否需要停止运行 3   private int tiketCount = 100000;    //总票数 4   private boolean lockTypeIsMethod = true; //是否是提供方法锁定还是代码块 5  6   public boolean isStop() { 7     return stop; 8   } 9   public void setStop(boolean stop) {10     this.stop = stop;11   }12 13   public boolean isLockTypeMethod() {14     return lockTypeIsMethod;15   }16   public void setLockTypeIsMethod(boolean lockTypeIsMethod) {17     this.lockTypeIsMethod = lockTypeIsMethod;18   }19 20   @Override21   public void run() {22     while (tiketCount > 0 && !stop) {23       try {24         Thread.sleep(50);  //延时,方便演示25       } catch (InterruptedException e) {26         e.printStackTrace();27       }28 29       //如果是通过锁定方法30       if (lockTypeIsMethod) {31         sale();32       } else {33         synchronized (this) {34           if (tiketCount > 0 && !stop) {35             System.out.println("使用代码块锁定:threadId="36                 + Thread.currentThread().getName() + ",ticketNO:" + tiketCount--);37           }38         }39       }40     }41   }42 43   public synchronized void sale() {44     if (tiketCount > 0 && !stop) {45       System.out.println("使用方法锁定:threadId="46           + Thread.currentThread().getName() + ",ticketNO:" + tiketCount--);47     }48   }49 }

线程定义类

 

Java中线程总结Java中线程总结
 1 public static void main(String[] args) throws InterruptedException { 2   ThreadTest threadTest = new ThreadTest();  //共享变量ThreadTest 3   //启用四个线程 4   new Thread(threadTest).start(); 5   new Thread(threadTest).start(); 6   new Thread(threadTest).start(); 7   new Thread(threadTest).start(); 8   //模拟设置共享变量, 9   // 1.交替使用方法体和代码块来进行线程同步实验10   // 2.模拟线程停止11   for (int i = 0; i < 100; i++) {12     Thread.sleep(1000);13     threadTest.setLockTypeIsMethod(i % 2 == 0);14     if (i == 50) {15       threadTest.setStop(true);16     }17   }18 }

调用端

  b). 演示线程通讯,本处模拟两个线程以生产和消费者角色读写一个集合的示例,其中当集合中有数据的时候通知消费者处理数据,处理完后通知生产者往集合中放入数据

Java中线程总结Java中线程总结
 1 //数据仓库 2 public class DataRepository { 3   private List<String> data = new ArrayList<>(); 4   private boolean hasData; 5  6   public boolean HasData() { 7     return hasData; 8   } 9 10   public void setHasData(boolean hasData) {11     this.hasData = hasData;12   }13 14   //放入数据15   public synchronized void put(List<String> data) throws InterruptedException {16     //生产者放入数据的时候,如果还有数据则等待.17     if (hasData) {18       wait();19     }20     this.data = data;21     hasData = true;22     //放入完毕后通知消费者23     notify();24   }25 26   //读取数据27   public synchronized List<String> get() throws InterruptedException {28     //没有数据则等待29     if (!hasData) {30       wait();31     }32     //获取数据副本返回33     List<String> rs = new ArrayList<>(data);34     data.clear();35     hasData = false;36     notify();37     return rs;38   }39 }

数据仓库
Java中线程总结Java中线程总结
 1 public class Producer implements Runnable { 2   private DataRepository dataRepository;   //数据仓库 3   public Producer(DataRepository dataRepository) { 4     this.dataRepository = dataRepository; 5   } 6  7   public void run() { 8     while (true) { 9       try {10         Thread.sleep(1000);11       } catch (InterruptedException e) {12         e.printStackTrace();13       }14       List<String> temp = new ArrayList<>();15       temp.add("------------");16       temp.add("第一个数据");17       temp.add("第二个数据");18       temp.add("第三个数据");19       temp.add("第四个数据");20       temp.add("------------");21       try {22         dataRepository.put(temp);23       } catch (InterruptedException e) {24         e.printStackTrace();25       }26     }27   }28 }

生产者
Java中线程总结Java中线程总结
 1 public class Consumer implements Runnable { 2   private DataRepository dataRepository; 3  4   public Consumer(DataRepository dataRepository) { 5     this.dataRepository = dataRepository; 6   } 7  8   public void run() { 9     while (true) {10       try {11         Thread.sleep(1000);12       } catch (InterruptedException e) {13         e.printStackTrace();14       }15       try {16         List<String> data=dataRepository.get();17         if(data!=null&&!data.isEmpty()){18           for (String temp :data){19             System.out.println(temp);20           }21         }22       } catch (InterruptedException e) {23         e.printStackTrace();24       }25     }26   }27 }

消费者
Java中线程总结Java中线程总结
1 public class Client {2   public static void main(String[] args) throws InterruptedException {3  4     DataRepository dr=new DataRepository();5     new Thread(new Producer(dr)).start();  //启动生产者线程6     new Thread(new Consumer(dr)).start();  //启动消费者线程7   }8 }

调用端

 

后记:

  a). 多线程属于较基础的知识,我们首先需要了解其最基本的概念,才能在项目中游刃有余的应用;

  b).不管是什么语言,其所需要的理论支持均大同小异;

  c).回到最初的那个概念,在多线程中,能不需要线程互相通讯就尽量不要用,能不同步就尽量不要使用线程同步,能不使用多线程就尽量不要使用多线程,说得有些含糊,各位自己去参悟吧.

 




原标题:Java中线程总结

关键词:JAVA

*特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们: admin#shaoqun.com (#换成@)。
相关文章
我的浏览记录
最新相关资讯
海外公司注册 | 跨境电商服务平台 | 深圳旅行社 | 东南亚物流