`
AlexShaw
  • 浏览: 12879 次
  • 性别: Icon_minigender_1
  • 来自: 青岛
最近访客 更多访客>>
社区版块
存档分类
最新评论

黑马程序员_java学习日记_Java基础_多线程

阅读更多

--------------------- android培训java培训java学习型技术博客、期待与您交流! ----------------------

进程:一个正在执行的程序,用于标示空间,用于封装控制单元

       每一个进程执行都有一个执行顺序,该顺序是一个执行路径,或者叫一个控制单元

线程:进程中的一个独立的控制单元。线程在控制着进程的执行

一个进程中至少一个线程

Java虚拟机启动时会有一个进程,该进程中至少一个线程负责java程序的执行,而这个线程存在于main方法中

严格来讲虚拟机是多线程的,比如主线程和垃圾回收线程

创建一个线程的方法:继承thread 重写run 实现runnable

创建一个实例就是定义一个线程

MyThread m = new MyThread();

//该方法有两个作用:启动线程,调用run方法

m.start();

实际上,同一时间,CPU只能执行一个进程中的一个线程,多线程执行时有随机性

为什么重写run方法:如果未覆盖,start中执行的run方法时父类的run方法,run方法其实就是线程要执行的代码,例如主线程中要执行的代码存于main方法中

只有start方法才能开启线程

Waitsleep的区别,sleep在一段时间后会自动执行,而wait无法继续执行,只能主动还行notifyStop表示消亡线程

主动结束:调用stop

被动结束:程序执行完

阻塞状态,某个进程再等CPU执行权的状态叫阻塞状态,有执行资格

冻结状态,sleepwait,表示线程放弃了执行资格

线程的四个状态:冻结,消亡,运行,阻塞

setNamegetName设置获取名称

线程有自己默认的名称 可以通过new的时候在后面传入线程名称来修改

卖票程序

静态的生命周期太长,所以不定义静态

线程第二种实现方式:实现runnable接口

<!--[if !supportLists]-->1.         <!--[endif]-->实现runnable接口

<!--[if !supportLists]-->2.         <!--[endif]-->重写run方法

<!--[if !supportLists]-->3.         <!--[endif]-->实例化一个对象

<!--[if !supportLists]-->4.         <!--[endif]-->New一个Thread类对象,并将上面实例化的对象传进去(自定义的run方法所属的是runnable的实现类,所以要让线程去执行指定对象的run方法)

<!--[if !supportLists]-->5.         <!--[endif]-->调用Thread类对象的start方法

接口和父类实现线程的区别:就是实现和继承的区别 即功能性扩展

接口的run方法存在于接口的子类中,而继承则存在于Thread的子类中

publicclass MySecondThrad {

 

    publicstaticvoid main(String[] args) {

       //只有thread类或其子类才能开启线程

       test m = new test();

       Thread t1 = new Thread(m);

       Thread t2 = new Thread(m);

       Thread t3 = new Thread(m);

       Thread t4 = new Thread(m);

       t1.start();

       t2.start();

       t3.start();

       t4.start();

    }

}

class test implements Runnable

{

    privateintticket = 100;

    @Override

    publicvoid run() {

       while(true)

       {

           if(ticket > 0)

           {

              System.out.println("ticket"+ticket--);

           }

       }

    }

}

Run方法中的异常必须捕捉不能抛

多线程的安全问题:多条线程争先执行代码,导致共享数据的错误

同步代码块:优点安全缺点消耗资源

Synchronized(对象)

{

}

对象如同锁,持有锁的进程可以执行,没有持有锁的线程即使获得了执行权也无法执行

同步的前提

<!--[if !supportLists]-->1.      <!--[endif]-->必须要有两个以上的线程

<!--[if !supportLists]-->2.      <!--[endif]-->必须是多个线程使用同一个锁

不是所有的run方法里面的代码都要放在同步代码块中

判断哪些代码该同步:

<!--[if !supportLists]-->a)         <!--[endif]-->明确哪些代码是多线程代码

<!--[if !supportLists]-->b)        <!--[endif]-->明确哪些是共享数据

<!--[if !supportLists]-->c)         <!--[endif]-->明确哪些代码操作共享数据

同步函数默认调用this这个锁,如何验证

如果同步函数被静态修饰后,锁不再是this而是类对象(字节码文件对象)

单例设计模式

/**

     * 饿汉式

     */

    publicstaticfinal SingleDemo s = new SingleDemo();

    private SingleDemo(){}

    publicstatic SingleDemo getInstance(){

       returns;

    }

懒汉式

    /**

     * 懒汉式用于实例的延迟加载。

     * 懒汉式加锁效率较低,

     */

    publicstatic SingleDemo s = null;

    private SingleDemo() {

    }

    publicstatic SingleDemo getInstance()

    {

       if(null == s)

           {

           synchronized(SingleDemo.class)

           {

              if(null == s)

              {

                  s = new SingleDemo();

              }

              returns;

           }

           }

       else

           returns;

    }

}

死锁

class tryDeadLock implements Runnable

{

    Boolean b ;

    public tryDeadLock(Boolean b)

    {

    this.b = b;  

    }

    @Override

    publicvoid run() {

       while(true)

       {

           if(b){

              synchronized(lock.l1)

              {

                  synchronized(lock.l2)

                  {

                     System.out.println("111");

                  }

              }

           }

           else{

              synchronized(lock.l2)

              {

                  synchronized(lock.l1)

                  {

                     System.out.println("222");

                  }

              }

           }

       }  

    }

}

class lock{

    static lock l1 = new lock();

    static lock l2 = new lock();

}

publicclass DeadLock {

    publicstaticvoid main(String[] args) {

       tryDeadLock t1 = new tryDeadLock(true);

       tryDeadLock t2 = new tryDeadLock(false);

       Thread t3 = new Thread(t1);

       Thread t4 = new Thread(t2);

       t3.start();

       t4.start();

      

    }

}

多线程通信:多个线程操作同一个资源

等待唤醒机制

Wait notify notifyAll都用在同步中,这些方法必须由监视器调用即锁对象

锁是任意对象,所以定义在了object

只有同步才有锁的概念

为甚么定义在object中,因为这些方法在操作线程时,必须标记所操作的对象只有的锁,只有同一个锁上的被等待线程可以被同一个锁上的notify唤醒。等待和唤醒必须是同一把锁

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics