关于Java多线程小结

项目场景:数据采集需要多线程执行,在所有子线程结束后主线程写入文件采集时间的结束点,但是在数据采集的时候也读取这个时间点
问题:当多个线程在读文件的时候主线程同时在写文件,导致多个线程读到的时间不一致,或者就是线程读不到时间,出现数据丢失
解决:1.创建线程池代码如下
          ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()*5);
           for(int i = 0; i < 5; i++){
               executorService.execute(new ThreadDemo());
          }
           //禁止添加新的线程
           executorService.shutdown();
           //等待所有线程结束后执行
           if(executorService .awaitTermination(Long.MAX_VALUE, TimeUnit.MINUTES )){
              System. out.println("i am main thread" );
          }
     2.创建线程组
          ThreadGroup g= new ThreadGroup("g1" );
           for (int i = 0; i < 2; i++) {
              Thread t= new Thread(g ,new ThreadDemo());
               t.start();
          }
             // 获得当前线程组中线程数目, 包括可运行和不可运行的
          //当前的线程数为零时表示线程组的线程执行结束
           while(g .activeCount() > 0){
//               System.out.println("group1的当前的活跃数量:"+g.activeCount());
        }
        System. out.println("==g中所有线程执行结束===" );
     3.使用join(),线程会依次执行,会影响执行效率
     public class JoinDemo {
      public static void main(String[] argsthrows InterruptedException {
           for (int i = 0 ; i < 3 ; i++){
              JoinFoo foo = new JoinFoo();
               foo.start();
               foo.join();
          }
          System. out .println("main Thread over" );
     }
      static class JoinFoo extends Thread {
           int total ;
           @Override
           public void run(){
              System. out .println("thread 1 is running" ); 
               try {
                   Thread. sleep(2000);
              } catch (InterruptedException e ) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
              }
            System. out .println("thread 1 is over and set flag to 1"); 
          }
     }
}

public class ThreadDemo extends Thread{
     public int i = 0;
     public ThreadDemo(){
           super();
     }
     
     @Override
     public void run(){
          System. out.println(Thread.currentThread().getName()+ "====="+(++i ));
          System. out.println("子线程" +Thread.currentThread ().getName());
           try {
              Thread. sleep(1000);
          } catch (InterruptedException e ) {
               // TODO Auto-generated catch block
               e.printStackTrace();
          }
     }
     
}

对于单个线程等待的可使用标记
public class TestSync {
      private static int FLAG = 0;
      public static void main(String[] args) {
          Thread1 thread1 = new Thread1();
          System. out .println("thread 1 is start" );
           thread1.start();
           while (FLAG != 1) {
               // System.out.println("main thread is waiting");
          }
           FLAG = 0;
          System. out .println("main thread is back to work");
     }
      static class Thread1 extends Thread {
           int total ;
           public void run() {
              System. out .println("thread 1 is running" );
               for (int i = 0; i < 5; i++) {
                    total = total + i;
                   System. out .println("total = " total );
              }
              System. out .println("thread 1 is over and set flag to 1");
               FLAG = 1;
          }
     }
}
Java多线程是指在一个Java程序中同时执行多个线程,每个线程都是独立的执行流。Java中创建线程的方式有三种:继承Thread类、实现Runnable接口和实现Callable接口。每种方式都有其优缺点。 1. 继承Thread类创建线程类: ```java class MyThread extends Thread { public void run() { // 线程执行的代码 } } // 创建线程对象并启动线程 MyThread thread = new MyThread(); thread.start(); ``` 优点:简单易用,可以直接重写Thread类的run()方法。 缺点:由于Java不支持多继承,继承了Thread类就无法再继承其他类。 2. 实现Runnable接口创建线程类: ```java class MyRunnable implements Runnable { public void run() { // 线程执行的代码 } } // 创建线程对象并启动线程 Thread thread = new Thread(new MyRunnable()); thread.start(); ``` 优点:避免了单继承的限制,可以继续继承其他类或实现其他接口。 缺点:需要额外创建Thread对象,并将Runnable对象作为参数传递给Thread对象。 3. 实现Callable接口创建线程类: ```java class MyCallable implements Callable<Integer> { public Integer call() throws Exception { // 线程执行的代码 return 0; } } // 创建线程池对象 ExecutorService executor = Executors.newFixedThreadPool(1); // 提交Callable任务并获取Future对象 Future<Integer> future = executor.submit(new MyCallable()); // 获取线程执行结果 int result = future.get(); ``` 优点:可以获取线程执行的结果,并且可以抛出异常。 缺点:相对于前两种方式,使用Callable需要更多的代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值