码迷,mamicode.com
首页 > 编程语言 > 详细

黑马程序员——JAVA基础-多线程

时间:2015-11-09 10:39:47      阅读:208      评论:0      收藏:0      [点我收藏+]

标签:

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

线程:一个正在执行的程序。
多线程存在的意义: 
程序运行中至少有两个线程在运行,一个是主函数的主线程,另一个是垃圾回收的线程。
线程创建方式一:
继承Thread类.要覆盖其run方法,调用线程的start方法.
作用:1.启动线程
      2.运行run方法。目的是将自定义的代码存储在run方法中,让线程运行
cpu每次只执行一个程序,只是在快速的不同线程间切换,表现了多线程的随机性

class demo extends Thread{
  public void run(){
  }
}

run方法用于存储线程要运行的代码。

demo demo=new demo();创建对象就创建了一个线程。


run方法和 start方法

run方法  仅仅是对象调用方法,并没有运行线程
start方法  是开启线程并且执行线程中的run方法

线程都有自己默认的名称:
获取线程名称的方法。Thread.currentThread().getName()

currentThread() 获取当前线程对象
getName()   获取线程名称 

设置线程名称 SetName(); 或者构造方法传参

创建线程的第二种方式:实现Runnable接口。

创建线程 

Thread t=new Thread(new 对象名());

步骤:
1,定义类实现Runnable接口。
2,覆盖接口中的run方法(用于封装线程要运行的代码)。
3,通过Thread类创建线程对象;
4,将实现了Runnable接口的子类对象作为实际参数传递给Thread类中的构造函数。
      为什么要传递呢?因为要让线程对象明确要运行的run方法所属的对象。
5,调用Thread对象的start方法。开启线程,并运行Runnable接口子类中的run方法。
Ticket t=new Ticket();
/*
直接创建Ticket对象,并不是创建线程对象。
因为创建对象只能通过new Thread类,或者new Thread类的子类才可以。所以最终想要创建线程。既然没有了Thread类的子类,就只能用Thread类。
Thread t1=new Thread(t);//创建线程。
只要将t作为Thread类的构造函数的实际参数传入即可完成线程对象和t之间的关联

实现方式和继承方式有什么区别?
继承Thread类:线程代码块存放在Thread子类的run方法中
实现Runnable,线程代码存放在接口的子类的run方法中,可以被多实现。


继承方式有局限性。要被实现多线程的一个类 如果继承了父类 就不能再继承Thread类。


多线程安全:
安全产生的原因:当多条语句在操作同一个共享数据时,一个线程对多条语句只执行了一部分,还没有执行完,
另一个线程参与进来执行。导致共享数据的错误。

解决办法:
对多条操作共享数据的语句,只能让一个线程都执行完。在执行过程中,其他线程不可以参与执行。

方式:同步代码块:
synchronized(对象),火车卫生间案例  
{
  需要被同步的代码。(共享数据)
}

对象如同锁,持有锁的线程可以在同步中执行,没有持有锁的线程,即使获取cpu的执行权,也进不去,因为没有获取锁。


同步的前提:
1.必须要有两个或者两个以上的线程
2.必须多个线程必须使用同一个锁。
  必须保证同步中只能有一个线程在运行。


好处:解决了线程的安全问题

弊端:消耗了资源,多个线程需要判断锁。

线程间通信:多个线程在操作同一个资源,但是操作的动作不同。

1.是不是两个或两个以上的线程。解决办法 两个线程都要被同步。
2.是不是同一个锁。解决办法 找同一个对象作为锁。

等待唤醒机制。

wait后,线程就会存在线程池中,notify后就会将线程池中的线程唤醒。
notifyAll();唤醒线程池中所有的线程。
实现方法 :

给资源加个标记 flag   

synchronized(r)
{
 while(r.flag)//多个生产者和消费者   if(r.flag)//一个生产者和消费者
  r.wait();
  代码
   r.flag=true;
  r.notify();
  r.notifyAll();
}

上面三种方法都使用在同步中,因为要对持有监视器(锁)的线程操作。所以要使用在同步中,因为只有同步才具有锁。

为什么这些操作线程的方法要定义在object类中呢?
因为这些方法在操作同步中线程的是偶,都必须要表示它们所操作线程只有的锁。只有同一个锁上的被等待线程,可以被
同一个锁上的notify唤醒,不可以对不同锁中的线程进行唤醒。

也就是说,等待和唤醒必须是同一个锁,而锁可以是特意对象,可以被任意对象调用的方法定义在Object类中。


黑马程序员——JAVA基础-多线程

标签:

原文地址:http://www.cnblogs.com/chun2015/p/4949171.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!