• Javase之多线程(2)


    多线程(2)

    线程的生命周期

    新建:创建线程对象

    就绪:有执行资格,没有执行权

    运行:有资格运行,有执行权

    ​ 阻塞:由一些操作让线程处于改状态。没有执行资格,没有执行权,而通过另一些操作激活它,激活后处于就绪状态。

    死亡:线程对象变成垃圾,等待回收

    多线程的实现方式二

    实现Runnable接口

    步骤:

    ​ 1.自定义类实现Runnable接口

    ​ 2.重写run()方法

    ​ 3.创建自定义类的对象

    ​ 4.创建Theard类对象并把步骤3的对象作为参数传递。

    class T1 implements Runnable{
    
        @Override
        public void run() {
            for (int i = 0;i < 100;i++){
    
                System.out.println(Thread.currentThread().getName()+":"+i);
            }
        }
    }
    
    public class runabletest {
        public static void main(String[] args) {
            T1 t = new T1();
    
            //public Thread(Runnable target,String name)
            Thread t1 = new Thread(t,"线程a");
            Thread t2 = new Thread(t,"线程b");
    
    //        Thread t1 = new Thread(t);
    //        Thread t2 = new Thread(t);
    //        t1.setName("线程1");
    //        t2.setName("线程2");
            t1.start();
            t2.start();
    
        }
    }
    

    实现接口的好处

    1.可以避免由Java单继承带来的局限性。

    2.适合多个相同程序的代码去处理同一个资源的情况,把线程同程序的代码,数据有效的分离,较好的体现了面向对象的思想。

    线程安全问题

    导致线程安全问题产生原因(也是判断程序是否出现线程安全问题的批准)

    1.是否是多线程环境

    2.是否有共享数据

    3.是否有多条语句操作共享数据

    解决方案

    1和2的问题,是不能改变的。所以我们只能考虑改变3

    思想:

    ​ 把多条语句操作共享数据的代码包装成一个整体,让某个线程执行时,其它线程就不能执行。

    解决安全问题方案1

    同步代码块

    格式:synchronized(对象){需要同步的代码块;}

    对象是什么:任意对象

    需要同步的代码是那部分:多条语句操作共享数据

    synchronized (obj) {
                while (n > 0) {
                    try {
                        Thread.sleep(100);
                    }catch (Exception e){
                        System.out.println("线程结束");
                    }
                    System.out.println(Thread.currentThread().getName() + "使用" + ":" + (n--));
                }
            }
    

    注:同步可以解决安全问题的根本原因在对象上。该对象如同锁功能。多个线程必须使用同一把锁。

    1.同步代码块的锁对象是任意对象

    2.同步方法的格式:把同步关键字synchronized加到方法上

    ​ 其锁对象是this

    public synchronized void show(){
            while (n > 0) {
                try {
                    Thread.sleep(100);
                }catch (Exception e){
                    System.out.println("线程结束");
                }
                System.out.println(Thread.currentThread().getName() + "使用" + ":" + (n--));
            }
        }
    

    3.静态方法锁对象是类的字节码文件。

    同步的特点

    前提:多个线程

    解决问题时注意:多个对象使用同一把锁。

    好处:同步解决了多个线程的安全问题。

    弊端:当线程较多时,因为每个线程都会去判断同步的锁,会浪费资源,降低程序运行效率。

    如何保证集合是安全的

    1.Vector是线程安全的

    2.调用Collections中对应的方法

    List<String> s = Collections.synchronizedList(new ArrayList<String>());
    

    JDK5以后的Lock

    为了直接的表达如何加锁和释放锁,JDK5以后提供了一个新对象Lock

    Lock:

    ​ void lock();获取锁

    ​ void unlock() ;释放锁

    ReentrantLock是Lock的实现类。

    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    class T3 implements Runnable {
        private int n = 100;
        Lock l = new ReentrantLock();
    
        @Override
        public void run() {
            while (true) {
                l.lock();
                if (n>0)
                try {
                    Thread.sleep(100);
                } catch (Exception e) {
                    System.out.println("线程结束");
                }finally {
                    System.out.println(Thread.currentThread().getName() + "使用" + ":" + (n--));
                    l.unlock();
                }
            }
        }
    }
    
    public class Locktest {
        public static void main(String[] args) {
            T3 t = new T3();
    
            Thread t1 = new Thread(t,"线程a");
            Thread t2 = new Thread(t,"线程b");
            Thread t3 = new Thread(t,"线程c");
            t1.start();
            t2.start();
            t3.start();
        }
    }
    

    死锁问题

    如果出现同步嵌套,就容易产生死锁问题。

    问题描述

    指在两个或两个以上的线程在执行过程中,因争夺资源而产生的一种相互等待的现象。

    代码

    class MyLock{
        static Object objA = new Object();
        static Object objB = new Object();
    }
    
    class MyTheard extends Thread{
        boolean flag;
    
        public MyTheard(boolean flag){
            this.flag = flag;
        }
        public void run(){
            if (flag){
                synchronized (MyLock.objA){
                    System.out.println("if objA");
                    synchronized (MyLock.objB){
                        System.out.println("if objB");
                    }
                }
            }else {
                synchronized (MyLock.objB){
                    System.out.println("else objB");
                    synchronized (MyLock.objA){
                        System.out.println("else objA");
                    }
                }
            }
        }
    
    }
    
    public class Dielocktest {
        public static void main(String[] args) {
            MyTheard m1 = new MyTheard(true);
            MyTheard m2 = new MyTheard(false);
    
            m1.start();
            m2.start();
        }
    }
    
  • 相关阅读:
    XAML实例教程系列 依赖属性和附加属性
    分享Silverlight/Windows8/WPF/WP7/HTML5周学习导读(6月4日6月10日)
    QT GUI基本布局
    mqtt client libraries for c
    QT sqlite相关操作
    navicat 激活工具激活时必须断网 ,如果没有断网激活 激活过程中报如下错误 请卸载navicat 重新安装再行激活操作
    vmware 16 windows7企业版 tools安装不了 驱动签名验证
    虚拟机复制
    Install systemtap on Ubuntu 12.04
    DevOps的各个阶段
  • 原文地址:https://www.cnblogs.com/wf614/p/11673843.html
Copyright © 2020-2023  润新知