zoukankan      html  css  js  c++  java
  • 多线层相关

    创建线程的方式:

      1: 继承Thread

        

    package com.sxt.thread;
    /**
     * 创建线程方式一:
     * 1、创建:继承Thread+重写run
     * 2、启动: 创建子类对象 + start
     * @author 
     *
     */
    public class StartThread extends Thread{
        /**
         * 线程入口点
         */
        @Override
        public void run() {
            for(int i=0;i<20;i++) {
                System.out.println("一边听歌");
            }
        }
        public static void main(String[] args) {            
            //创建子类对象
            StartThread st =new StartThread();
            //启动 
            st.start(); //不保证立即运行 cpu调用
            //st.run(); //普通方法调用
            for(int i=0;i<20;i++) {
                System.out.println("一边coding");
            }
        }
    
    }
    View Code

      2: 实现Runnable接口

        

    package com.sxt.thread;
    /**
     * 创建线程方式二:
     * 1、创建:实现Runnable+重写run
     * 2、启动: 创建实现类对象 +Thread对象+ start
     * 
     * 推荐: 避免单继承的局限性,优先使用接口
     * 方便共享资源
     * @author 
     *
     */
    public class StartRun implements Runnable{
        /**
         * 线程入口点
         */
        @Override
        public void run() {
            for(int i=0;i<20;i++) {
                System.out.println("一边听歌");
            }
        }
        public static void main(String[] args) {            
            /*//创建实现类对象
            StartRun sr =new StartRun();
            //创建代理类对象
            Thread t =new Thread(sr);
            //启动 
            t.start(); //不保证立即运行 cpu调用
    */        
            new Thread(new StartRun()).start();
            
            //st.run(); //普通方法调用
            for(int i=0;i<20;i++) {
                System.out.println("一边coding");
            }
        }
    
    }
    View Code

      3:实现Callable接口(线程安全)

      

    package com.sxt.thread;
    
    import java.util.concurrent.Callable;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.Future;
    /**
     * 了解创建线程的方式三: 
     * 
     * @author 
     *
     */
    public class CDownloader implements Callable<Boolean>{
        private String url; //远程路径
        private String name;  //存储名字
        
        public CDownloader(String url, String name) {
            this.url = url; 
            this.name = name;
        }
    
        @Override
        public Boolean call() throws Exception {
            WebDownloader wd =new WebDownloader();
            wd.download(url, name);        
            System.out.println(name);
            return true;
        }
        
        public static void main(String[] args) throws InterruptedException, ExecutionException {
            CDownloader cd1 =new CDownloader("http://upload.news.cecb2b.com/2014/0511/1399775432250.jpg","phone.jpg");
            CDownloader cd2 =new CDownloader("http://p1.pstatp.com/large/403c00037462ae2eee13","spl.jpg");
            CDownloader cd3 =new CDownloader("http://5b0988e595225.cdn.sohucs.com/images/20170830/d8b57e0dce0d4fa29bd5ef014be663d5.jpeg","success.jpg");
            
            //创建执行服务: 
            ExecutorService  ser=Executors.newFixedThreadPool(3);
            //提交执行: 
            Future<Boolean> result1 =ser.submit(cd1) ;
            Future<Boolean> result2 =ser.submit(cd2) ;
            Future<Boolean> result3 =ser.submit(cd3) ;
            //获取结果:  
            boolean r1 =result1.get();
            boolean r2 =result1.get();
            boolean r3 =result1.get();
            System.out.println(r3);
            //关闭服务:  
            ser.shutdownNow();
    
        }
    }
    View Code

    lamda表达式 

            new Thread(()->{
                //run方法
                
            }).start();
    View Code

    线程控制方法:

      sleep

        暂停: 当前线程被阻塞,任务回到待添加状态;

          如果调用了sleep方法之后,没有其他等待执行的线程,这个时候当前线程不会马上恢复执行

      yield

        礼让: 让当前正在执行的线程暂停,不是阻塞线程,而是将线程从运行状态转为就绪状态,让CPU调度器重新调用.

           如果调用了yield方法之后,没有其他等待执行的线程,这个时候当前线程就会马上恢复执行

      join

        插队: 阻塞指定线程等到另一个线程完成以后再继续执行

    设置优先级:

      

    package com.test.thread;
    
    public class PriorityTest {
    
        public static void main(String[] args) {
            
            MyPriority myPriority = new MyPriority();
            
            Thread t1 = new Thread(myPriority, "线程一");
            Thread t2 = new Thread(myPriority, "线程二");
            Thread t3 = new Thread(myPriority, "线程三");
            Thread t4 = new Thread(myPriority, "线程四");
            Thread t5 = new Thread(myPriority, "线程五");
            Thread t6 = new Thread(myPriority, "线程六");
            
            //设置优先级在启动前
            t1.setPriority(Thread.MAX_PRIORITY);
            t2.setPriority(Thread.MIN_PRIORITY);
            t3.setPriority(Thread.NORM_PRIORITY);
            t4.setPriority(8);
            t5.setPriority(7);
            t6.setPriority(1);
            
            t1.start();
            t2.start();
            t3.start();
            t4.start();
            t5.start();
            t6.start();
    
            /**
            线程一===>10
            线程三===>5
            线程二===>1
            线程四===>8
            线程五===>7
            线程六===>1
    
             */
        }
    
    }
    
    class MyPriority implements Runnable {
        
        @Override
        public void run() {
            // TODO Auto-generated method stub
            System.out.println(Thread.currentThread().getName() + "===>" + Thread.currentThread().getPriority());
        }
    }
    View Code

    守护线程:

      setDatmon(false),默认为false

      守护线程是为用户线程服务的,jvm停止不用等待守护线程执行完毕

      默认:jvm等待用户线程执行完毕才会停止

    isAlive: 线程是否还活着

    setName: 设置名称(代理角色的名称,如果是真实角色的名称,向真实角色对象设置name属性)

    getName:

    Thread.currentThread():

    线程安全:

      如果只是对数据进行读取,不需要考虑线程安全;如果是读取后需要改动数据,则需要考虑线程安全问题

    并发:

      同一个对象被多个线程同时操作

    synchronized:

     synchronized方法: 锁this

     synchronized块: 锁具体对象,一般就是要修改的对象

    package com.test.thread;
    
    public class CinemaTest02 {
    
        public static void main(String[] args) {
    
            Cinema2 c2 = new Cinema2(3, "官网");
            Customer2 ct1 = new Customer2(c2, "张三", 2);
            Customer2 ct2 = new Customer2(c2, "李四", 1);
            
            ct1.start();
            ct2.start();
        }
    
    }
    
    class Customer2 extends Thread {
        int seats;
        
        
        public Customer2 (Runnable target, String nameString, int seats) {
            super(target, nameString);
            this.seats = seats;
        }
    }
    
    
    class Cinema2 implements Runnable {
        
        int available;
        String nameString;
        
        
        
        public Cinema2(int available, String nameString) {
            this.available = available;
            this.nameString = nameString;
        }
    
    
    
        @Override
        public void run() {
    
            Customer2 ct = (Customer2)Thread.currentThread();
            
            boolean flag = getTickets(ct.seats);
            
            if (flag) {
                System.out.println("购票成功" + "===>" + "剩余票数" + available);
            }else {
                System.err.println("出票失败");
            }
        }
        
        
        public synchronized boolean getTickets(int tiketsNum) {
            
            if (available - tiketsNum >= 0) {
                available -= tiketsNum;
                return true;
            }else {
                return false;
            }
        }
        
        
    }
    View Code

    模拟售票:

    package com.test.thread;
    
    public class BuyTicketTest {
    
        public static void main(String[] args) {
            
            //同一份资源
            SaleTickets sale = new SaleTickets();
            
            //被多个线程同时调用
            new Thread(sale, "张三").start();
            new Thread(sale, "李四").start();
            new Thread(sale, "王五").start();
    
        }
    
    }
    
    
    
    class SaleTickets implements Runnable {
        
        private int ticketsNumber = 5;
        private boolean flag = true;
        
        @Override
        public void run() {        
            
            while (flag) {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }        
                sale();
    
            }
    
        }
        
        /*
         * synchronized块,锁住具体对象
         */
        public void sale() {
            
            //如果没有票了,线程不进行等待,提高效率
            if (ticketsNumber <= 0) {
                flag = false;
                return;
            }
            
            //flag,ticketsNumber都需要进行修改,锁住this
            synchronized (this) {
                if (ticketsNumber <= 0) {
                    flag = false;
                    return;
                }
                
                System.out.println("当前剩余票数--->" + ticketsNumber-- + "---->" + Thread.currentThread().getName());
    
            }
    
        }
        
        /**
         * synchronized 方法, 锁住this
         * 线程安全  同步
         */
        public synchronized void sale2() {
            if(ticketsNumber<=0) {
                flag = false;
                return ;
            }
            //模拟延时
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("当前剩余票数--->" + ticketsNumber-- + "---->" + Thread.currentThread().getName());
        }
    
        
    }
    View Code

    容器:

    package com.sxt.syn;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * 线程安全:操作容器
     * 
     * @author 
     *
     */
    public class SynBlockTest02 {
        public static void main(String[] args) throws InterruptedException {
            List<String> list = new ArrayList<String>();
            for(int i=0;i<10000;i++) {
                new Thread(()->{
                    //同步块
                    synchronized(list) {
                        list.add(Thread.currentThread().getName());
                    }
                }) .start();
            }
            Thread.sleep(10000);
            System.out.println(list.size());
        }
    }
    View Code

    CopyOnWriteArrayList 并发容器:

    package com.sxt.syn;
    
    import java.util.ArrayList;
    import java.util.concurrent.CopyOnWriteArrayList;
    import java.util.List;
    
    /**
     * 线程安全:操作并发容器
     * 
     * @author 
     *
     */
    public class SynContainer {
        public static void main(String[] args) throws InterruptedException {
            CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<String>();
            for(int i=0;i<10000;i++) {
                new Thread(()->{
                    list.add(Thread.currentThread().getName());
                }) .start();
            }
            Thread.sleep(10000);
            System.out.println(list.size());
        }
    }
    View Code

    synchronized块模拟影院售票:

    package com.test.thread;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class CinemaTest {
    
        public static void main(String[] args) {
            
            List<Integer> list1 = new ArrayList<Integer>();
            list1.add(1);
            list1.add(2);
            list1.add(3);
            list1.add(4);
            list1.add(5);
            list1.add(6);
            list1.add(7);
            
            
            List<Integer> list2 = new ArrayList<Integer>();
            list2.add(1);
            list2.add(2);
            list2.add(3);
    
    
            List<Integer> list3 = new ArrayList<Integer>();
    
            list3.add(1);
            list3.add(6);
            list3.add(7);
    
            
            Cinema cinema = new Cinema(list1, "百老汇");
            
            Customer c1Customer = new Customer(list2, cinema);
            Customer c2Customer = new Customer(list3, cinema);
            
            new Thread(c1Customer).start();
            new Thread(c2Customer).start();
        }
    
    }
    
    
    class Customer implements Runnable {
        List<Integer> seats;
        Cinema cinema;
        public Customer(List<Integer> seats, Cinema cinema) {
    
            this.seats = seats;
            this.cinema = cinema;
        }
        
        public Customer() {
    
        }
        
        
        @Override
        public void run() {
            
            synchronized (cinema) {
                boolean flag = cinema.getTickets(seats);
                
                if (flag) {
                    System.out.println("欢迎光临" + cinema.name + "===>" + "购票成功" + "===>" + "购票位置为" + seats + "===>" + "剩余票数" + cinema.available);
                }else {
                    System.out.println("购票失败");
                    
                }
    
            }
            
        }
    
        
        
    }
    
    
    class Cinema {
        List<Integer> available;
        String name;
        public Cinema(List<Integer> available, String name) {
    
            this.available = available;
            this.name = name;
        }
        
        public boolean getTickets(List<Integer> ticktesNums) {
            
            List<Integer> copyList = new ArrayList<Integer>();
            copyList.addAll(available);
            copyList.removeAll(ticktesNums);
            System.out.println("ticktesNums: " + ticktesNums);
    
            System.out.println("copyList剩座位" + copyList);
            
            if (available.size() == ticktesNums.size() + copyList.size() ) {
                available = copyList;
                return true;
            }else {
    
                return false;
            }
        }
        
    }
    View Code

     synchronized方法模拟影院售票:

    package com.test.thread;
    
    public class CinemaTest02 {
    
        public static void main(String[] args) {
    
            Cinema2 c2 = new Cinema2(3, "官网");
            Customer2 ct1 = new Customer2(c2, "张三", 2);
            Customer2 ct2 = new Customer2(c2, "李四", 1);
            
            ct1.start();
            ct2.start();
        }
    
    }
    
    class Customer2 extends Thread {
        int seats;
        
        
        public Customer2 (Runnable target, String nameString, int seats) {
            super(target, nameString);
            this.seats = seats;
        }
    }
    
    
    class Cinema2 implements Runnable {
        
        int available;
        String nameString;
        
        
        
        public Cinema2(int available, String nameString) {
            this.available = available;
            this.nameString = nameString;
        }
    
    
    
        @Override
        public void run() {
    
            Customer2 ct = (Customer2)Thread.currentThread();
            
            boolean flag = getTickets(ct.seats);
            
            if (flag) {
                System.out.println("购票成功" + "===>" + "剩余票数" + available);
            }else {
                System.err.println("出票失败");
            }
        }
        
        
        public synchronized boolean getTickets(int tiketsNum) {
            
            if (available - tiketsNum >= 0) {
                available -= tiketsNum;
                return true;
            }else {
                return false;
            }
        }
        
        
    }
    View Code

    Timer 

    package com.sxt.others;
    
    import java.util.Calendar;
    import java.util.GregorianCalendar;
    import java.util.Timer;
    import java.util.TimerTask;
    
    /**
     * 任务调度: Timer 和TimerTask类
     * 
     * @author 
     *
     */
    public class TimerTest01 {
    
        public static void main(String[] args) {
            Timer timer = new Timer();
            //执行安排
            //timer.schedule(new MyTask(), 1000);  //执行任务一次
            //timer.schedule(new MyTask(), 1000,200); //执行多次
            Calendar cal = new GregorianCalendar(2099999,12,31,21,53,54);
            timer.schedule(new MyTask(), cal.getTime(),200); //指定时间
        }
    
    }
    //任务类
    class  MyTask extends TimerTask{
    
        @Override
        public void run() {
            for(int i=0;i<10;i++) {
                System.out.println("放空大脑休息一会");
            }
            System.out.println("------end-------");
        }
        
    }
    View Code

    Volatile

    volatile保证线程间变量的可见性,简单地说就是当线程A对变量X进行了修改,在线程A后面执行的其他线程能看到变量X的变动,更详细的说是要符合以下两个规则:

      1: 线程对变量进行修改之后,要立刻回写到主内存

      2: 线程对变量读取的时候,要从主内存中读,而不是缓存

    各线程的工作内存间彼此独立,互不可见,在线程启动的时候,虚拟机为每个内存分配一块工作内存,不仅包含了线程内部定义的局部变量,也包含了线程所需要使用的(非线程内构造的对象)的副本,即为了提高执行效率

      volatile是不错的机制,但volatile不能保证原子性

      现在机器性能比较强大,很少出现线程忙不过的情况,所以volatile在开发中较少使用

    package com.sxt.others;
    /**
     * volatile用于保证数据的同步,也就是可见性
     * 
     * @author 
     *
     */
    public class VolatileTest {
        private volatile static int num = 0;
        public static void main(String[] args) throws InterruptedException {
            new Thread(()->{
                while(num==0) { //此处不要编写代码
                    // 不加volatile,此处死循环
                }
            }) .start();
            
            Thread.sleep(1000);
            num = 1;
        }
    
    }
    View Code

    DCL单例模式:

    package com.sxt.others;
    /**
     * DCL单例模式: 懒汉式套路基础上加入并发控制,保证在多线程环境下,对外存在一个对象
     * 1、构造器私有化 -->避免外部new构造器
     * 2、提供私有的静态属性 -->存储对象的地址
     * 3、提供公共的静态方法 --> 获取属性
     * 
     * 
     *
     */
    public class DoubleCheckedLocking {
        //2、提供私有的静态属性
        //没有volatile其他线程可能访问一个没有初始化的对象
        private static volatile DoubleCheckedLocking instance;    
        //1、构造器私有化 
        private DoubleCheckedLocking() {        
        }
        //3、提供公共的静态方法 --> 获取属性
        public static DoubleCheckedLocking getInstance() {    
            //再次检测
            if(null!=instance) { //避免不必要的同步 ,已经存在对象
                return instance;
            }
            synchronized(DoubleCheckedLocking.class) {
                if(null == instance) {                
                    instance = new DoubleCheckedLocking();
                    //1、开辟空间 //2、初始化对象信息 //3、返回对象的地址给引用
                }
            }
            return instance;
        }    
        public static DoubleCheckedLocking getInstance1(long time) {        
                if(null == instance) {
                    try {
                        Thread.sleep(time);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    instance = new DoubleCheckedLocking();
                    //1、开辟空间 //2、初始化对象信息 //3、返回对象的地址给引用
                }
            return instance;
        }
        public static void main(String[] args) {
            Thread t = new Thread(()->{
                System.out.println(DoubleCheckedLocking.getInstance());
            }) ;
            t.start();
            System.out.println(DoubleCheckedLocking.getInstance());
        }
    
    }
    View Code

    ThreadLocal:

    package com.sxt.others;
    /**
     * ThreadLocal:每个线程自身的存储本地、局部区域
     *  get/set/initialValue
     * @author 裴新 QQ:3401997271
     *
     */
    public class ThreadLocalTest01 {
        //private static ThreadLocal<Integer> threadLocal = new ThreadLocal<> ();
        //更改初始化值
        /*private static ThreadLocal<Integer> threadLocal = new ThreadLocal<> () {
            protected Integer initialValue() {
                return 200;
            }; 
        };*/
        private static ThreadLocal<Integer> threadLocal = ThreadLocal.withInitial(()-> 200);
        public static void main(String[] args) {
            //获取值
            System.out.println(Thread.currentThread().getName()+"-->"+threadLocal.get());//main-->200
            //设置值
            threadLocal.set(99);
            System.out.println(Thread.currentThread().getName()+"-->"+threadLocal.get());//main-->99
    
            
            new Thread(new MyRun()).start();
            new Thread(new MyRun()).start();
        }    
        public static  class MyRun implements Runnable{
            public void run() {
                threadLocal.set((int)(Math.random()*99));//Thread-1-->28; Thread-0-->65
    
                System.out.println(Thread.currentThread().getName()+"-->"+threadLocal.get());        
            }
        }
        
    }
    View Code
    package com.sxt.others;
    /**
     * ThreadLocal:每个线程自身的数据,更改不会影响其他线程
     *     Thread-0得到了-->1
        Thread-0还剩下-->0
        Thread-1得到了-->1
        Thread-2得到了-->1
        Thread-1还剩下-->0
        Thread-3得到了-->1
        Thread-4得到了-->1
        Thread-2还剩下-->0
        Thread-4还剩下-->0
        Thread-3还剩下-->0
    
     *
     */
    public class ThreadLocalTest02 {    
        private static ThreadLocal<Integer> threadLocal = ThreadLocal.withInitial(()-> 1);
        public static void main(String[] args) {
            for(int i=0;i<5;i++) {
                new Thread(new MyRun()).start();
            }
        }    
        public static  class MyRun implements Runnable{
            public void run() {
                Integer left =threadLocal.get();
                System.out.println(Thread.currentThread().getName()+"得到了-->"+left);        
                threadLocal.set(left -1);
                System.out.println(Thread.currentThread().getName()+"还剩下-->"+threadLocal.get());    
            }
        }
        
    }
    View Code
    package com.sxt.others;
    /**
     * ThreadLocal:分析上下文 环境  起点
     * 1、构造器: 哪里调用 就属于哪里 找线程体
     * 2、run方法:本线程自身的
     * 
     *
     */
    public class ThreadLocalTest03 {    
        private static ThreadLocal<Integer> threadLocal = ThreadLocal.withInitial(()-> 1);
        public static void main(String[] args) {
            new Thread(new MyRun()).start();
            new Thread(new MyRun()).start();
        }    
        public static  class MyRun implements Runnable{
            public MyRun() {
                threadLocal.set(-100);
                System.out.println(Thread.currentThread().getName()+"-->"+threadLocal.get());    
            }
            public void run() {
                System.out.println(Thread.currentThread().getName()+"-->"+threadLocal.get());    
                //new Thread(new MyRunxxx()).start();
            }
        }
        
    }
    
    
    /*
     *     main-->-100
        main-->-100
        Thread-0-->1
        Thread-1-->1
     * */
    View Code
    package com.sxt.others;
    /**
     * InheritableThreadLocal:继承上下文 环境的数据 ,拷贝一份给子线程
     * 
     *     main-->2
        Thread-0-->2
        Thread-0-->200
     *
     */
    public class ThreadLocalTest04 {    
        private static ThreadLocal<Integer> threadLocal = new InheritableThreadLocal<>();
        public static void main(String[] args) {
            threadLocal.set(2);
            System.out.println(Thread.currentThread().getName()+"-->"+threadLocal.get());    
            
            //线程由main线程开辟
            new Thread(()->{
                System.out.println(Thread.currentThread().getName()+"-->"+threadLocal.get());    
                threadLocal.set(200);
                System.out.println(Thread.currentThread().getName()+"-->"+threadLocal.get());    
            }) .start();
            
        }    
        
        
    }
    View Code

      

  • 相关阅读:
    解决SpringMVC中jsp页面无法加载js,css,jpg中的信息
    浅谈SpringMVC
    Java垃圾回收与算法
    Linux常见命令
    Warm_up(HCTF_2018)
    house_of_storm 详解
    malloc 函数分析 glibc2.23
    Fastbin attack 总结
    Unlink学习总结
    xman_2019_format(非栈上格式化字符串仅一次利用的爆破)
  • 原文地址:https://www.cnblogs.com/jiefangzhe/p/11362071.html
Copyright © 2011-2022 走看看