Java线程学习笔记(一)

来源:互联网 发布:反智主义 知乎 编辑:程序博客网 时间:2024/05/16 04:41

一、线程的创建方式:

老掉牙的话题了,继承 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睡眠8000main醒来

可以看出,后台进程不受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设计模式》。


0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 孕妇吃了黑橄榄怎么办 内膜4mm来月经了怎么办 吃了伟哥没效果怎么办 维a酸乳膏副作用怎么办 颈椎病引起的头晕恶心怎么办 经常头疼怎么办最快最有效 感昌了头晕乏力怎么办 来例假喝啤酒了怎么办 来月经喝啤酒了怎么办 吃的油腻长痘怎么办 兔子拉黑色稀便怎么办 宝宝补钙便秘了怎么办 吃了肾宝片上火怎么办 吃肾宝片就上火怎么办 吃肾宝片后上火怎么办 孕妇吃了扁桃仁怎么办 怀孕吃了扁桃仁怎么办 经期吃了阿胶糕怎么办 10儿童咳嗽有痰怎么办 6岁宝宝咳嗽有痰怎么办 儿童6岁咳嗽有痰怎么办 零号胶囊用多了怎么办 7岁半乳房发育,怎么办 妊娠斑怎么办,能去掉吗 跨域访问被拒绝怎么办 月子里半夜饿了怎么办 5岁儿童包茎该怎么办 6岁儿童包茎该怎么办 1岁半乳房发育,怎么办 4岁智力发育迟缓怎么办 儿童换牙长得慢怎么办 幼儿牙齿长得慢怎么办 小孩骨骼发育不好该怎么办 宝宝身高长得慢怎么办 多肉生长点坏了怎么办 试管胚胎长得慢怎么办 来月经头痛想吐怎么办 经期量多时间长怎么办 49岁例假不规律怎么办 45岁例假不规律怎么办 16岁例假不规律怎么办