• Java线程学习笔记(一个)


    一个、正在创建的线程:

    老掉牙的话题了。继承 java.lang.Thread父类或者实现Runnalbe接口。这里就提一句:

    class Thread implements Runnable
    Thread也是继承了Runnable接口的,Runnable才是大哥。

    重写run(),run()里放的都是详细的业务,包含对线程的详细操作。

    class Thread1 implements Runnable {
        int i;
        Thread1(int i) {
            this.i = i;
        }
        @Override
        public void run() {
            long x = new Random().nextInt(10)*1000;
            try {
                Thread.sleep(x);
            } catch (InterruptedException e) {
                e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
            }
            System.out.println("线程"+ i + "睡眠" + x);
        }
    }
    二、线程的调用:

    独立的线程启动方式—Thread的start()方式,

    class Thread1Execute {
        public static void main(String[] args) {
            // 创建线程
            Thread thread = new Thread(new Thread1(99));
            // 启动命令
            thread.start();
        }
    }
    线程池启动 ExecutorService

    public class SleepTest1 {
        public static void main(String[] args) {
            // 创建线程池,这里用了向上造型。事实上newCachedThreadPool出来的类是ThreadPoolExecutor。
            ExecutorService executor = Executors.newCachedThreadPool();
            for (int i=0;i<10 ; i++) {
                // 运行10个线程
                executor.execute(new Thread1(i));
            }
            //关闭线程池 
            executor.shutdown();
        }
    }

    三、线程优先级:

    线程里设置优先级。JDK里有10个优先级,但JDK得优先级与操作系统兼容的并不好,因此,在编程的时候。仅仅是用三个优先级

       /**
         * The minimum priority that a thread can have. 
         */
        public final static int MIN_PRIORITY = 1;
    
       /**
         * The default priority that is assigned to a thread. 
         */
        public final static int NORM_PRIORITY = 5;
    
        /**
         * The maximum priority that a thread can have. 
         */
        public final static int MAX_PRIORITY = 10;</span>

    设置优先级的代码要放到run()的开头部分。

    public void run() {
        // 设置优先级为最高。
        Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
    }

    四、让步Thread.yield()

    yield()方法仅仅只是是一个暗示,不能保证它被採用。因此。在对重要的线程进行控制的时候,慎用。

    五、后台线程

    后台线程也叫守护线程,顾名思义就是在后台跑的线程,不会因正常线程的结束而结束。 

    设置方法为,在线程启动之前,thread.setDaemon(true);

    由于Thread默认的daemon是false,參照代码例如以下:

    /* Whether or not the thread is a daemon thread. */
        private boolean    daemon = false;
    代码演示样例:

    class Thread1Execute {
        public static void main(String[] args) throws InterruptedException {
            for (int i=0;i<10 ; i++) {
                // 创建线程
                Thread thread = new Thread(new Thread1(i));
                thread.setDaemon(true);
                // 启动命令
                thread.start();
            }
            System.out.println("main睡眠");
            Thread.sleep(10000);
            System.out.println("main醒来");
        }
    }
    输出结果为:

    main睡眠
    线程6睡眠2000
    线程8睡眠2000
    线程3睡眠3000
    线程7睡眠4000
    线程1睡眠5000
    线程0睡眠5000
    线程9睡眠5000
    线程5睡眠7000
    线程4睡眠8000
    线程2睡眠8000
    main醒来
    

    能够看出,后台进程不受Main线程的控制。在main睡眠期间,他们依旧辛劳耕种。

    但当最后一个非后台线程退出时,后台线程会“突然”终止,也就是说一旦main()退出。JVM将关闭全部后台线程。

    因此,这样的后台线程并不好控制。不推荐在实际项目中使用。


    另一种线程池的创建后台进程的方式。这样的方式略微有那么一点点复杂

    Executors.newCachedThreadPool(new DaemonThreadFactory());这里须要传入一个线程工厂。

    public static void main(String[] args) throws Exception {
            ExecutorService exec = Executors.newCachedThreadPool(new DaemonThreadFactory());
            for(int i = 0; i < 10; i++)
                exec.execute(new DaemonFromFactory());
            System.out.println("All daemons started");
            TimeUnit.MILLISECONDS.sleep(500); // Run for a while
        }
    工厂的定义例如以下,作用为将全部创建出来的线程都设置为Daemon后台线程类型。


    class DaemonThreadFactory implements ThreadFactory {
        @Override
        public Thread newThread(Runnable r) {
            Thread t = new Thread(r);
            t.setDaemon(true);
            return t;
        }
    }

    这样的灵感来源于java.util.concurrent.Executors的默认线程工厂。

       /**
         * The default thread factory
         */
        static class DefaultThreadFactory implements ThreadFactory {
            static final AtomicInteger poolNumber = new AtomicInteger(1);
            final ThreadGroup group;
            final AtomicInteger threadNumber = new AtomicInteger(1);
            final String namePrefix;
    
            DefaultThreadFactory() {
                SecurityManager s = System.getSecurityManager();
                group = (s != null)? s.getThreadGroup() :
                                     Thread.currentThread().getThreadGroup();
                namePrefix = "pool-" +
                              poolNumber.getAndIncrement() +
                             "-thread-";
            }
    
            public Thread newThread(Runnable r) {
                Thread t = new Thread(group, r,
                                      namePrefix + threadNumber.getAndIncrement(),
                                      0);
                if (t.isDaemon())
                    t.setDaemon(false);
                if (t.getPriority() != Thread.NORM_PRIORITY)
                    t.setPriority(Thread.NORM_PRIORITY);
                return t;
            }
        }
    
    


    先讲这么多,线程这块的东西实在是太多了,理解起来也很难。

    有那么一本书推荐一下《JAVA并发编程实践》这本书是专门讲并发的,我打算下个月就開始写那本书的阅读日记,当然还有传说中的《Head first设计模式》。


    版权声明:本文博客原创文章,博客,未经同意,不得转载。

  • 相关阅读:
    Exam Results(尺取)
    Exam Results(尺取)
    CF 1437C Chef Monocarp (背包dp)
    CF 1437C Chef Monocarp (背包dp)
    leecode-143.重排列表(链表,指针)
    leecode-143.重排列表(链表,指针)
    leecode-1.俩数之和(map)
    leecode-1.俩数之和(map)
    牛客多校(2020第三场)F Fraction Construction Problem
    牛客多校(2020第三场)F Fraction Construction Problem
  • 原文地址:https://www.cnblogs.com/blfshiye/p/4634979.html
Copyright © 2020-2023  润新知