zoukankan      html  css  js  c++  java
  • java多线程技能

    1.进程和线程的定义

      进程:受操作系统管理的基本运行单元

      线程:进程中独立运行的子任务

    2.使用多线程

      2.1继承Thread类:自定义线程类并继承Thread类,并且重写run方法。

    class MyThread extends Thread
    {    
        private int count=1000;
        @Override
        public void run() {
            // TODO Auto-generated method stub
            for(int i=0;i<500;i++){
                count--;
                System.out.println(Thread.currentThread().getId()+":"+count);    
            }
            
        }
    }
    
    public class Test {
        /**
         * @param args
         * @throws ClassNotFoundException 
         * @throws IOException 
         */
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            MyThread myThread=new MyThread();
            for(int i=0;i<2;i++){
                Thread thread=new Thread(myThread);
                thread.start();
            }
            
        
        }
    
    }
    View Code

      Thread类start()方法其实就是开始接受由操作系统分配的时间片,一但当前线程接受到时间片就开始执行run()方法

      2.2实现Runnable接口(推荐)

    class MyThread implements Runnable
    {    
        private int count=1000;
        @Override
        public void run() {
            // TODO Auto-generated method stub
            for(int i=0;i<500;i++){
                count--;
                System.out.println(Thread.currentThread().getId()+":"+count);    
            }
            
        }
    }
    
    public class Test {
        public static void main(String[] args) throws ClassNotFoundException, IOException {
            // TODO Auto-generated method stub
            MyThread myThread=new MyThread();
            for(int i=0;i<2;i++){
                Thread thread=new Thread(myThread);
                thread.start();
            }    
        }
    }
    View Code

    3.实例变量和线程安全

      3.1不共享数据的情况

    class MyThread extends Thread
    {    
        private int count=10;
        @Override
        public void run() {
            // TODO Auto-generated method stub
            for(int i=0;i<5;i++){
                count--;
                System.out.println(Thread.currentThread().getId()+":"+count);    
            }
            
        }
    }
    
    public class Test {
        public static void main(String[] args){
            // TODO Auto-generated method stub        
            for(int i=0;i<2;i++){
                Thread thread=new MyThread();
                thread.start();
            }    
        }
    }
    View Code  

      3.2共享数据的情况

    class MyThread extends Thread
    {    
        private int count=10;
        @Override
        public void run() {
            // TODO Auto-generated method stub
            for(int i=0;i<5;i++){
                count--;
                System.out.println(Thread.currentThread().getId()+":"+count);    
            }
            
        }
    }
    
    public class Test {
        public static void main(String[] args){
            // TODO Auto-generated method stub    
            Thread thread1=new MyThread();
            for(int i=0;i<2;i++){
                Thread thread=new Thread(thread1);
                thread.start();
            }    
        }
    }
    View Code

      3.3非线程安全:多个线程对同一个对象实例的变量进行操作时,出现值不同步、被其它线程更改进而影响程序的执行。

    4.停止线程

      4.1Thread类interrupt()方法中断线程,该方法实质上只是改变了线程的中断状态,所以就算interrupt()方法被调用,

      线程还是会继续执行直至结束。  

    class MyThread extends Thread
    {        
        @Override
        public void run() {
            for(int i=0;i<Integer.MAX_VALUE;i++)
            {
                if(!this.interrupted())
                {
                    System.out.println(i);
                }
                else
                {
                    System.out.println("当前线程被中断,我要退出");
                    break;
                }
            }
            System.out.println("这里是线程被中止后的输出,理论上线程被中止 我不应该被输出");//
        }
    }
    
    public class Test {
        public static void main(String[] args){
            // TODO Auto-generated method stub    
            Thread thread1=new Thread(new MyThread());
            thread1.start();
            try {
                Thread.sleep(2000);
                thread1.interrupt();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                System.out.println("main catch");
                e.printStackTrace();
            }                
        }
    }
    View Code

      运行结果:

       ……  

      328198
      328199
      328200
      328201
      328202
      328203
      328204
      当前线程被中断,我要退出
      这里是线程被中止后的输出,理论上线程被中止 我不应该被输出

      4.2异常法中止线程:获取到当前线程的中止状态为true后抛出InterruptedException异常

    class MyThread extends Thread
    {        
        @Override
        public void run() {
            try
            {
                for(int i=0;i<Integer.MAX_VALUE;i++)
                {
                    if(!this.interrupted())
                    {
                        System.out.println(i);
                    }
                    else
                    {
                        System.out.println("当前线程被中断,我要退出");
                        throw new InterruptedException();
                    }
                }
                System.out.println("这里是线程被中止后的输出,理论上线程被中止 我不应该被输出");//
            }
            catch(Exception e)
            {
                System.out.println("进入到异常");//
            }
    
        }
    }
    
    public class Test {
        public static void main(String[] args){
            // TODO Auto-generated method stub    
            Thread thread1=new Thread(new MyThread());
            thread1.start();
            try {
                Thread.sleep(2000);            
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                System.out.println("main catch");
                e.printStackTrace();
            }        
            thread1.interrupt();    
            
        }
    }
    View Code

      4.3使用return 中止线程:

    class MyThread extends Thread
    {        
        @Override
        public void run() {
            for(int i=0;i<Integer.MAX_VALUE;i++)
            {
                if(!this.interrupted())
                {
                    System.out.println(i);
                }
                else
                {
                    System.out.println("当前线程被中断,我要退出");
                    return;
                }
            }
            System.out.println("这里是线程被中止后的输出,理论上线程被中止 我不应该被输出");//        
        }
    }
    
    public class Test {
        public static void main(String[] args){
            // TODO Auto-generated method stub    
            Thread thread1=new Thread(new MyThread());
            thread1.start();
            try {
                Thread.sleep(2000);            
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                System.out.println("main catch");
                e.printStackTrace();
            }        
            thread1.interrupt();    
            
        }
    }
    View Code

    5.暂停和恢复线程

      5.1suspend和resume的使用  

    class MyThread extends Thread
    {        
        @Override
        public void run() {
            for(int i=0;i<Integer.MAX_VALUE;i++)
            {
                System.out.println(i);
            }            
        }
    }
    
    public class Test {
        public static void main(String[] args) throws InterruptedException{
            // TODO Auto-generated method stub    
            Thread thread1=new Thread(new MyThread());
            thread1.start();
            while(true)
            {
                Thread.sleep(3000);
                thread1.suspend();
                Thread.sleep(3000);
                thread1.resume();    
            }        
        }
    }
    View Code

      5.2suspend和resume方法的缺点-独占

      在当前线程使用suspend和resume方法时,其它线程将无法访问公共同步对象。

    class MyThread extends Thread
    {        
        @Override
        public void run() {
            for(int i=0;i<Integer.MAX_VALUE;i++)
            {
                System.out.println(i);
                if(i>100)
                {
                    this.currentThread().suspend();
                }
            }            
        }
    }
    public class Test {
        public static void main(String[] args) throws InterruptedException{
            // TODO Auto-generated method stub    
            MyThread myThread=new MyThread();
            Thread thread1=new Thread(myThread);
            Thread thread2=new Thread(myThread);
            thread1.start();
            Thread.sleep(3000);
            thread2.start();    
        }
    }
    View Code

      5.3suspend和resume方法的缺点-不同步

      容易出现因为线程的暂停而导致数据的不同步

    class MyThread extends Thread
    {        
        private String username="a";
        private String password="a1";
        public void SetValue(String u,String p) throws InterruptedException
        {
            this.username=u;        
            if(u=="b")
            {
                this.currentThread().suspend();
                Thread.sleep(4000);
                this.currentThread().resume();
            }        
            this.password=p;
        }
        
        @Override
        public void run() {
            System.out.println(this.currentThread().getId()+"username:"+username);
            System.out.println(this.currentThread().getId()+"password:"+password);
        }
    }
    
    public class Test {
        public static void main(String[] args) throws InterruptedException{
            // TODO Auto-generated method stub    
            MyThread myThread=new MyThread();
            Thread thread1=new Thread(myThread);
            thread1.start();
            myThread.SetValue("b", "b1");
        
            
    
        }
    }
    View Code

    6.yield方法:暂停当前正在执行的线程对象,并执行其他线程。放弃当前CPC分配给它的时间片,但放弃的时间不确定。

  • 相关阅读:
    51 张图助你彻底掌握 HTTP
    Nginx从原理到实战
    vu3.0 + ts + swiper6 的问题
    使用 react-router-dom v5 查询query 参数的方法
    visual studio 2015配置SVN
    SVN使用教程总结
    C#与SAP进行数据交互
    shell csv/txt文件对比
    persto array_join(array_agg(),',')
    shell 拼接html table 发送邮件
  • 原文地址:https://www.cnblogs.com/liandy0906/p/6810639.html
Copyright © 2011-2022 走看看