• java线程介绍(原创)


    文章讲解要点

    1.线程创建几种方式
    2.线程常见设置方法,包括优先级、优先级休眠、停止等
    3.多线程间的数据交互与锁机制
    4.项目源码下载

     
    线程介绍.png

    一、线程创建方式

    常见的线程创建方法以下三种:

    1.使用继承Thread类的方式

    public class CreateThread1{
    
        static class TestThread extends Thread {
    
            public void run() {
    
                for (int i = 0; i < 50; i++) {
    
                    System.out.println(i + " 多线程1...");
    
                }}
            }
    
        static class TestThread2 extends Thread {
    
                public void run() {
    
                    for (int i = 0; i < 500; i++) {
    
                        System.out.println(i + " 多线程2...");
    
                    }
                }
                }
    
         public static void main(String[] args) {
    
            TestThread testThread = new TestThread();
    
            TestThread2 testThread2 = new TestThread2();
    
             testThread.start();//启动线程
    
             testThread2.start();//启动线程
    
             for (int i = 0; i < 10000; i++)
            {
    
                System.out.println(i + " 主线程...");
    
            }
        }
    
    }
    

    运行结果如下:

     

    温馨提示:该方法缺点是:线程类已经继承了Thread类,所以不能再继承其他父类

    2.采用实现Runnable方式

    public class CreateThread2 {
    
        static class TestRunnable implements Runnable {
            public void run() {
                for (int i = 0; i < 500; i++) {
                    System.out.println(i + " 多线程1...");
                }
            }
        }
    
        static class TestRunnable2 implements Runnable {
            public void run() {
                for (int i = 0; i < 500; i++) {
                    System.out.println(i + " 多线程2...");
                }
            }
        }
    
        public static void main(String[] args) {
    
            TestRunnable testRunnable = new TestRunnable();
    
            TestRunnable2 testRunnable2 = new TestRunnable2();
    
            new Thread(testRunnable).start();//启动线程
    
            new Thread(testRunnable2).start();//启动线程
    
            for (int i = 0; i < 10000; i++) {
                System.out.println(i + " 主线程...");
            }
        }
    
    }
    

    运行结果如下:

     

    3.匿名内部类

    该方法比较少用,此处不进行详细介绍。

    二、线程常见设置方法

    通用线程类

    public class CurrencyThread {
    
        public static class TestThread extends Thread {
    
            public void run() {
    
                for (int i = 0; i < 50; i++) {
    
                    System.out.println(i + " 多线程1...");
    
                }
            }
        }
    
        public static class TestThread2 extends Thread {
    
            public void run() {
    
                for (int i = 0; i < 500; i++) {
    
                    System.out.println(i + " 多线程2...");
    
                }
            }
        }
    }
    

    线程优先级设置

    1.记住当线程的优先级没有指定时,所有线程都携带普通优先级
    2.优先级可以用从1到10的范围指定。10表示最高优先级,1表示最低优先级,5是普通优先级
    3.记住优先级最高的线程在执行时被给予优先。但是不能保证线程在启动时就进入运行状态
    4.由调度程序决定哪一个线程被执行
    5.t.setPriority()用来设定线程的优先级
    6.记住在线程开始方法被调用之前,线程的优先级应该被设定

    public class ThreadPriority {
    
        public static final int MIN_PRIORITY = 1;//最低优先级
    
        public static final int NORM_PRIORITY = 5;//普通优先级
    
        public static final int MAX_PRIORITY = 10;//最大优先级
    
        public static void main(String[] args) {
    
            CurrencyThread.TestThread testThread = new CurrencyThread.TestThread();
    
            CurrencyThread.TestThread2 testThread2 = new CurrencyThread.TestThread2();
    
            testThread.setPriority(NORM_PRIORITY);
    
            testThread.setPriority(MAX_PRIORITY);
    
            testThread.start();//启动线程
    
            testThread2.start();//启动线程
    
            for (int i = 0; i < 10000; i++)
            {
    
                System.out.println(i + " 主线程...");
    
            }
    
        }
    
    }
    
    

    运行结果如下:

     

    线程休眠

    线程休眠方法为:sleep();

    public class CommonSettings {
    
        public static void main(String[] args) throws InterruptedException {
    
            TestThread testThread = new TestThread();
    
            testThread.start();
    
        }
    }
    
    class TestThread extends Thread {
    
        public void run() {
    
            for (int i = 0; i < 50; i++) {
    
                System.out.println("当前值为:" + i + "当前时间为:" + new Date());
    
                    try {
    
                        sleep(2000);//线程休眠2s
    
                    } catch (InterruptedException e) {
    
                        e.printStackTrace();
    
                    }
    
            }
        }
    }
    

    运行结果如下:

     

    线程暂停与恢复

      暂停线程使用Thread中的suspend()方法;恢复暂停的线程使用resume()方法;但两个方法已经不推荐使用了,详情查看源代码

    线程中断

      实现方法为:interrupt();并不能使线程结束运行,只是告知线程有一个中断请求,线程不断地检测中断状态,以便进行相应地操作.比如停止线程操作。停止线程操作:不断地检测中断状态,如果产生中断,使用return或者break结束线程,详情查看源代码

    三、多线程间的数据交互与锁机制

    为什么要使用锁机制
    我们所熟知的Java锁机制无非就是Sychornized 锁 和 Lock锁
    Synchronized是基于JVM来保证数据同步的,而Lock则是在硬件层面,依赖特殊的CPU指令实现数据同步的

    • Synchronized,它就是一个:非公平,悲观,独享,互斥,可重入的重量级锁
    • ReentrantLock,它是一个:默认非公平但可实现公平的,悲观,独享,互斥,可重入,重量级锁。
    • ReentrantReadWriteLocK,它是一个,默认非公平但可实现公平的,悲观,写独享,读共享,读写,可重入,重量级锁。

    Synchronized的作用:

    在JDK1.5之前都是使用synchronized关键字保证同步的,它可以把任意一个非NULL的对象当作锁。

    1. 作用于方法时,锁住的是对象的实例(this);
    2. 当作用于静态方法时,锁住的是Class实例,又因为Class的相关数据存储在永久带PermGen(jdk1.8则是metaspace),永久带是全局共享的,因此静态方法锁相当于类的一个全局锁,会锁所有调用该方法的线程;
    3. synchronized作用于一个对象实例时,锁住的是所有以该对象为锁的代码块。

      了解了锁机制之后,我们进一步了解线程间数据共享与不共享
      不共享数据的多线程:不共享数据就是每个都是独立的线程

    public class ThreadLock {
    
        /**
         * 测试不共享数据的多线程
         */
        static class NotShareThread extends Thread {
    
            private int count=5;
    
            public NotShareThread(String name){
    
                super();
    
                this.setName(name);
    
            }
    
            @Override
    
            public void run(){
    
                super.run();
    
                while(count>0){
    
                    count--;
    
                    System.out.println(Thread.currentThread().getName()+"此时的count="+count);
    
                }
    
            }
    
        }
    public static void main(String[] args) {
    
            //测试不共享数据的多线程
            NotShareThread nsd1= new NotShareThread("01");
    
            NotShareThread nsd2= new NotShareThread("02");
    
            NotShareThread nsd3= new NotShareThread("03");
    
            nsd1.start();
    
            nsd2.start();
    
            nsd3.start();
    
        }
    }
    

    运行结果如下:

     

    共享数据的多线程:共享数据的情况就是多个线程可以访问同一个对象

    public class ThreadLock {
    /**
         * 数据共享的线程测试
         */
        static class ShareThread extends Thread {
    
            private int count=5;
    
            @Override
    
            public void run(){
    
                super.run();
    
                System.out.println(Thread.currentThread().getName() + "此时访问了");
    
                synchronized (this)
                {
                    count--;
    
                    System.out.println(Thread.currentThread().getName()+"此时的count="+count);
    
                    try {
    
                        sleep(2000);
    
                    } catch (InterruptedException e) {
    
                        e.printStackTrace();
                    }
                }
    
            }
    
        }
    
        public static void main(String[] args) {
    
            ShareThread st = new ShareThread();
    
            //用的是同一个对象,就实现了数据共享了
            Thread t1=new Thread(st,"1");
    
            Thread t2=new Thread(st,"2");
    
            Thread t3=new Thread(st,"3");
    
            Thread t4=new Thread(st,"4");
    
            Thread t5=new Thread(st,"5");
    
            t1.start();
    
            t2.start();
    
            t3.start();
    
            t4.start();
    
            t5.start();
    
        }
    }
    

    运行结果如下:

     


    实际应用场景介绍
       大家可以看到我们在代码块中加入了synchronized锁机制,以保证数据的同步,因为在某些实际项目操作中,数据的操作必须保持唯一性,比如银行存款取款操作。

    1. 不采用锁机制:
      现ATM机的管理中心余额为1000元,有两个人同时在操作ATM机器,一人存500,一人取50,第一个人操作完成时,管理中心显示余额为1500,第二个人操作完成时,管理中心显示余额为950,但是实际真的是这样的吗?我们再来看看锁机制的处理方式是怎样的!

    2. 采用锁机制:
      现ATM机的管理中心余额为1000元,有两个人同时在操作ATM机器,一人存500,一人取50,在第一个人未完成操作时,第二个人是处于交易处理中的,当一个人存钱完成时,第二个人获取到管理中心余额为1500元后再进行取款,之后管理中心显示余额为1450元。

    四、项目源码下载

    链接:https://pan.baidu.com/s/10Hw9lQ5RiAGLVlFaEz4p0A
    提取码:x5br

  • 相关阅读:
    隐藏 MOSS 2007 页面版本工具栏
    用于显示原始XML形式的搜索结果的XSLT
    MOSS 2007 日志设置
    在布局页面“文章页面中”添加,自定义UserControl
    MOSS 2007 最简单的自定义搜索框 SearchBox
    Asp.net常用状态管理方案分析
    提高asp.net的性能的几种方法(转)
    VS2005下如何用预编译命令来发布站点
    asp.net控件设计时支持(1)
    解决Enterprise Library January 2006不能加密配置文件的方法(转)
  • 原文地址:https://www.cnblogs.com/WUXIAOCHANG/p/10550388.html
Copyright © 2020-2023  润新知