zoukankan      html  css  js  c++  java
  • day24 Java学习 多线程

    多线程(多线程的引入)

          线程 :

                * 线程是程序执行的一条路径,一个进程中可以包含多条线程。

                * 多线程并发执行可以提高程序的效率,可以同时完成多项工作。

          应用场景:

                * 服务器同时处理多个客户端请求。

    多线程(多线程并行和并发的区别) 

                * 并行就是两个任务同时运行,就是甲任务进行的同时,乙任务也在运行。( 需要多个cpu)

                * 并发是指两个任务都请求运行,而处理器只能接收一个任务,就把这两个任务安排轮流进行,由于时间间隔较短,使人感觉两个任务都在运行。

    多线程(多线程程序实现的方式 ) 

        * extends Thread:

    public class Dome1_Thread {
    
    public static void main(String[] args) {
            // 
             MyThread my=new MyThread();       //4.创建MyThread子类对象
             my.start();                       //5.statr()开启线程
             for (int i = 0; i <10; i++) {
                System.out.println("b");
                
            }
        }
    
    }
     
     class MyThread extends Thread{     //1.继承Thread
         public void run() {            //2.重写run()
            for (int i = 0; i < 10; i++) {   //3.将要执行的代码放在run()中 
                System.out.println("aaa");
                
            }
            for (int i = 0; i < 10; i++) {   //将要执行的代码放在run()中 
                System.out.println("ccc");
                
            }
        }
     }
    例子

        *  implements Runnable:

    public class Dome1_Thread {
    
        public static void main(String[] args) {
            //
            MyRunnable mr = new MyRunnable();  //4.创建Runnable的子类对象
            Thread t = new Thread(mr);         //5.将其当作参数传递给Thread的构造函数
            t.start();                         //6.开启线程
            for (int i = 0; i < 10; i++) {
                System.out.println("b");
    
            }
        }
    
    
    }
     class MyRunnable implements Runnable{      //1.定义一个类实现Runnable
    
        @Override
        public void run() {                     //2.重写run()
            for (int i = 0; i < 10; i++) {      //3.将要执行的代码放在run()中 
                System.out.println("aaa");
                
            }    
        }      
     }
    例子

    两种方式的区别:

        * 继承Thread 

                    * 好处是:可以直接使用Thread类中的方法,代码简单。

                    * 弊端是:如果已经有了父类,就不能用这种方法。

         * 实现Runnable接口:

                    * 好处是:即使自己定义的线程类有了父类也没关系,因为父类也可以实现接口,而且接口是可以多实现的。

                    * 弊端是:不能直接使用Thread中的方法需要先获取线程对象后才能得到Thread的方法。

    多线程(匿名内部类实现线程)

      

    public static void main(String[] args) {
            //方法1:
            new Thread() {                              // 1.继承Thread()
                public void run() {                     // 2.重写run()
                    for (int i = 0; i <= 10; i++) {     // 3.将要执行的代码放在run()中
                        System.out.println("aaa");
                    }
                }
            }.start();                                   // 4.statr()开启线程
            
            //方法2:
            new Thread( new Runnable() {              //1.将Runnable的子类对象传递给Thread的构造方法
                public void run() {                   // 2.重写run()
                    for (int i = 0; i <= 10; i++) {   // 3.将要执行的代码放在run()中
                        System.out.println("bbb");
                    }
                } 
            }).start();                               // 4.statr()开启线程
        }
    例子

    多线程(获取当前线程的对象)

      * Thread.currentThread() :获取当前正在执行的线程。

    public static void main(String[] args) {
            new Thread() {                              
                public void run() {    
                    System.out.println(this.getName() + "...aaa"); 
                }
            }.start();
    
            new Thread( new Runnable() {              
                public void run() {                 
                    //Thread.currentThread()获取当前正在执行的线程
                        System.out.println(Thread.currentThread().getName() +"...bbb");        
                } 
            }).start();    
            // 设置主线程名字
            Thread.currentThread().setName("陈琳狗");
            //获取主线程名字
            System.out.println(Thread.currentThread().getName());
    
        }
    例子

    多线程(休眠线程)

      * Thread.sleep(毫秒 ,纳秒):控制当前线程休眠若干毫秒

       (1秒=1000 毫秒      1秒=1000*1000*1000 纳秒)

    多线程(守护线程)

      *  setDaemon( ) :设置一个线程为守护线程,该线程不会单独执行,当其他非守护线程都执行结束后,自动推出。( 当传入为true就是意味着设置为守护线程。)

    多线程(加入线程)

      *  join( ) :当前线程暂停,等待指定的线程执行结束后,当前线程再继续。

     *  join( int ) :可以等待指定的毫秒之后继续。

    public static void main(String[] args) {
        final    Thread t1 = new Thread() {
                public void run() {
                    for (int i = 0; i < 10; i++) {
                        System.out.println(getName() + "....aaa");
                    }
                }
            };
            
            Thread t2 = new Thread() {
                public void run() {
                    for (int i = 0; i < 10; i++) {
                        if (i==2) {
                            try {
    //                            t1.join();
                                t1.join(1); // 插队指定时间,过了指定时间后,两条线程交替执行
                            } catch (InterruptedException e) {
                                // TODO 自动生成的 catch 块
                                e.printStackTrace();
                            }
                        }
                        System.out.println(getName() + "....bbbbbb");
                    }
                }
            };
        t1.start();
        t2.start();
        
        }
    例子

    多线程(设置线程的优先级)

    setPriority (Thread .MIN_PRIORITY);

    setPriority (Thread .MAX_PRIORITY);

    多线程(同步代码块)

    synchronized( ){  } :同步代码块,锁机制,锁对象可以是任意的(锁对象不能用匿名对象,因为匿名对象不是同一个对象)。

    使用情况:

                     * 当多线程并发,有多段代码同时执行时,我们希望某一段代码执行的过程中CPU不要切换到其他线程工作,这时就需要同步。

                     * 如果两段代码块是同步的,那么同一时间只能执行一段,在一段代码块没执行结束之前,不会执行另外一段代码。

    同步代码块:多个同步代码如果使用相同的锁对象,那么他们就是同步的。

    public class Dome1_Synchronized {
    
        public static void main(String[] args) {
            final printss p = new printss();
            new Thread() {
                public void run() {
                    while (true) {
                        p.print1();
                    }
                }
            }.start();
    
            new Thread() {
                public void run() {
                    while (true) {
                        p.print2();
                    }
                }
            }.start();
    
        }
    
    }
    
    class printss {
        Dome d=new Dome();
        public void print1() {
              synchronized (d) {        //synchronized(){} :同步代码块,锁机制,锁对象可以是任意的(锁对象不能用匿名对象,因为匿名对象不是同一个对象)
                System.out.print("a");
            System.out.print("b");
            System.out.print("c");
            System.out.println("
    ");
            }
                
            
            
        }
        
        public void print2() {
            synchronized (d) {
                System.out.print("e");
                System.out.print("f");
                System.out.print("g");
                System.out.println("
    ");
            }
    
        }
    }
    
    class Dome{
        
    }
    例子

    多线程(同步方法)

    同步方法只需要在方法上加synchronized关键字即可。

    public synchronized void print1() {   //同步方法只需要在方法上加synchronized关键字即可。
              System.out.print("a");
                System.out.print("b");
                System.out.print("c");
                System.out.println("
    ");
        }
        
        public void print2() {                //非静态的同步方法的锁对象是this
            synchronized (this) {                     
                System.out.print("d");
            System.out.print("e");
            System.out.print("f");
            System.out.println("
    ");
            }
            
        }
        
        
    非静态的同步方法
    //静态同步方法
    class printstatic{
        public  synchronized void print1() {   //同步方法只需要在方法上加synchronized关键字即可。
              System.out.print("a");
                System.out.print("b");
                System.out.print("c");
                System.out.println("
    ");
        }
        
        public void print2() {               
            synchronized (printstatic.class) {  //静态的同步方法的锁对象是该类的字节码对象
                System.out.print("d");
            System.out.print("e");
            System.out.print("f");
            System.out.println("
    ");
            }        
        }
    }
    静态的同步方法

    多线程(线程安全问题)

       * 多线程并发操作同一数据时,就有可能出现线程安全问题。

       * 使用同步技术可以解决这种问题,把操作数据的代码进行同步,不要多个线程一起操作。

    public class Dome3_Ticket {
    
        public static void main(String[] args) {
            //需求:卖100张票,四个窗口
            new Ticket().start();
            new Ticket().start();
            new Ticket().start();
            new Ticket().start();
        }
    
    }
    
    class Ticket extends Thread{
            private static int ticket=100;      //增加Static静态使四个线程公用一个ticket
    //        private static Object object=new Object();   //如果用引用数据类型成员变量当作锁对象,必须是静态的。 
            public void   run() {
                while (true) {
                    synchronized (Ticket.class) {
                        if (ticket<=0) {
                        break;
                    }
                        try {
                            Thread.sleep(10);
                        } catch (InterruptedException e) {
                            // TODO 自动生成的 catch 块
                            e.printStackTrace();
                        }
                    System.out.println(getName()+"...这是第"+ticket--+"号票");
                    }
                    
                }
                
            }
    
    }
    例子
    public class Dome_Ticket {
    
        public static void main(String[] args) {
            // Runnable接口实现火车站卖票例子 4个窗口
                MyTicket mt= new MyTicket();
                new Thread(mt).start();
                new Thread(mt).start();
                new Thread(mt).start();
                new Thread(mt).start();
        }
    
    }
    
    class MyTicket implements Runnable{
            private int ticket=100;
        @Override
        public void run() {
            while (true) {
                synchronized (Ticket.class) {
                    if (ticket<=0) {
                    break;
                }
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        // TODO 自动生成的 catch 块
                        e.printStackTrace();
                    }
                System.out.println(Thread.currentThread().getName()+"...这是第"+ticket--+"号票");
                }    
            }
            
        }
        
    }
    Runnable接口实现

    多线程(死锁)

        多线程同步的时候,如果同步代码块嵌套,使用相同的锁,就有可能出现死锁。(尽量不要嵌套使用) 

  • 相关阅读:
    内核模块的一些问题
    [转]change the linux startup logo
    raspbian 静态IP
    [转]centos7 配置yum源(本地+光盘)
    [转]source inslght使用指导
    T420修改wifi灯闪动模式
    root运行chrome
    [转]理解阻塞非阻塞与同步异步
    [转] 计算机体系架构分类
    Win7下安装 Oracle Virtual Box
  • 原文地址:https://www.cnblogs.com/feng0001/p/10977260.html
Copyright © 2011-2022 走看看