多线程技术

继承Thread

public class MyThread extends Thread {
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println("哈哈哈"+i);
        }
    }
}
public class Test {
    public static void main(String[] args)  {
        MyThread m = new MyThread();
        m.start();
        for (int i = 0; i < 10; i++) {
            System.out.println("aaa"+i);
        }
    }
}

实现Runnable接口

public class MyRunnable implements Runnable {

    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println("窗前明月光"+i);
        }
    }
}
/**
 * 多线程技术
 *实现Runnable与继承Thread相比有如下优势:
 * 1.通过创建任务,然后给线程分配的方式来实现多线程,更适合多个线程同时执行相同任务的情况
 * 2.可以避免单继承所带来的局限性
 * 3.任务与线程本身是分离的,提高了程序的健壮性
 */
public class Test {
    public static void main(String[] args)  {
       //实现Runnable
        //1.创建一个任务对象
        MyRunnable r = new MyRunnable();
        //2.创建一个线程,并为其分配一个任务
        Thread t = new Thread(r);
        //3.执行这个线程
        t.start();
        for (int i = 0; i < 10; i++) {
            System.out.println("疑似地上霜"+i);
        }
    }
}

线程中断

public class Test {
    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(new MyRunnable());
        t1.start();
        for (int i = 0; i < 5; i++) {
            System.out.println(Thread.currentThread().getName()+":"+i);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();

            }
        }
        //给线程t1添加中断标记
        t1.interrupt();
    }

    static class MyRunnable implements Runnable {
        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {
                System.out.println(Thread.currentThread().getName()+":"+i);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    //e.printStackTrace();
                    return;
                }
            }
        }
    }
}

守护线程

/**
 * 多线程技术
 * 线程:分为守护线程和用户线程
 * 用户线程:当一个进程不包含任何的存活的用户线程时,进行结束
 * 守护线程:守护用户线程的,当最后一个用户线程结束时,所有守护线程自动死亡
 */
public class Test {
    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(new MyRunnable());
        //设置t1为守护线程
        t1.setDaemon(true);
        t1.start();
        for (int i = 0; i < 5; i++) {
            System.out.println(Thread.currentThread().getName()+":"+i);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();

            }
        }

    }

    static class MyRunnable implements Runnable {
        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {
                System.out.println(Thread.currentThread().getName()+":"+i);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    //e.printStackTrace();
                    return;
                }
            }
        }
    }
}

线程安全

同步代码块

public class Test {
    public static void main(String[] args) {
        Runnable run = new Ticket();
        new Thread(run).start();
        new Thread(run).start();
        new Thread(run).start();
    }

    static class Ticket implements Runnable {
        //票数
        private int count = 10;
        //定义一个锁的对象
        private Object o = new Object();

        @Override
        public void run() {
            while (true) {
                //把需要执行的代码锁起来
                synchronized (o) {
                    if (count > 0) {
                        System.out.println("开始卖票:");
                        //睡眠1s
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        count--;
                        System.out.println(Thread.currentThread().getName() + "出票成功,余票:" + count);
                    } else {
                        break;
                    }
                }
            }
        }
    }

}

同步方法

public class Test {
    public static void main(String[] args) {
        Runnable run = new Ticket();
        new Thread(run).start();
        new Thread(run).start();
        new Thread(run).start();
    }

    static class Ticket implements Runnable {
        //票数
        private int count = 10;
        //定义一个锁的对象
        private Object o = new Object();

        @Override
        public void run() {
            while (true) {
                //把需要执行的代码锁起来
                boolean flag = sale();
                if (!flag) {
                    break;
                }
            }
        }

        public synchronized boolean sale() {
            if (count > 0) {
                System.out.println("开始卖票:");
                //睡眠1s
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                count--;
                System.out.println(Thread.currentThread().getName() + "出票成功,余票:" + count);
                return true;
            }
            return false;
        }

    }


显示锁Lock

public class Test {
    public static void main(String[] args) {
        Runnable run = new Ticket();
        new Thread(run).start();
        new Thread(run).start();
        new Thread(run).start();
    }

    static class Ticket implements Runnable {
        //票数
        private int count = 10;
        //显示锁
        private Lock l = new ReentrantLock();

        @Override
        public void run() {
            while (true) {
                //把需要执行的代码锁起来
                l.lock();
                if (count > 0) {
                    System.out.println("开始卖票:");
                    //睡眠1s
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    count--;
                    System.out.println(Thread.currentThread().getName() + "出票成功,余票:" + count);
                }else{
                    break;
                }
                l.unlock();
            }
        }
    }
}

缓存线程池

缓存线程池.
* (长度无限制)
* 执行流程:
* 1. 判断线程池是否存在空闲线程
* 2. 存在则使用
* 3. 不存在,则创建线程 并放入线程池, 然后使用
public class Demo03 {
    public static void main(String[] args) {
        ExecutorService service = Executors.newCachedThreadPool();
        //指挥线程池中执行新的任务
        service.execute(new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+"床前明月光");
            }
        });
        service.execute(new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+"床前明月光");
            }
        });
        service.execute(new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+"床前明月光");
            }
        });
        //睡眠一秒钟测试下面代码是不是调用线程池中空闲的线程
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        service.execute(new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+"床前明月光");
            }
        });
    }
}

定长线程池

* 定长线程池.
* (长度是指定的数值)
* 执行流程:
3. 单线程线程池
4. 周期性任务定长线程池
* 1. 判断线程池是否存在空闲线程
* 2. 存在则使用
* 3. 不存在空闲线程,且线程池未满的情况下,则创建线程 并放入线程池, 然后使用
* 4. 不存在空闲线程,且线程池已满的情况下,则等待线程池存在空闲线程
public class Demo04 {
    public static void main(String[] args) {
        //线程池中有两个线程
        ExecutorService service = Executors.newFixedThreadPool(2);
        service.execute(new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+":1");
                //为了测试睡眠三秒
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        service.execute(new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+":2");
                //为了测试睡眠三秒
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        service.execute(new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+":3");
            }
        });
    }
}

单线程线程池

单线程线程池.
* 执行流程:
* 1. 判断线程池的那个线程是否空闲
* 2. 空闲则使用
* 4. 不空闲,则等待池中的单个线程空闲后使用
public class Demo05 {
    public static void main(String[] args) {
        ExecutorService service = Executors.newSingleThreadExecutor();
        service.execute(new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+":1");
            }
        });
        service.execute(new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+":1");
            }
        });
        service.execute(new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+":1");
            }
        });
    }
}

周期定长线程池

public class Demo06 {
    public static void main(String[] args) {
        ScheduledExecutorService service = Executors.newScheduledThreadPool(2);
        /*
        定时执行一次
            参数1:定时执行任务
            参数2:时长数字
            参数3:时长数字的时间单位,TimeUnit的常量指定
         */
       /* service.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("1");
            }
        },3, TimeUnit.SECONDS);
        */
        /*
            周期性执行任务
            参数1:任务
            参数2:延迟时长数字(第一次执行在什么时间以后)
            参数3:周期时长数字(每隔多久执行一次)
            参数4:时长数字的单位
         */
        service.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                System.out.println(1);
            }
        },5,1,TimeUnit.SECONDS);//5s中之后开始执行,每个1s执行一次
    }
}

你可能感兴趣的:(多线程技术)