A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 天亮1 中级黑马   /  2018-12-6 14:18  /  1282 人查看  /  4 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

Java多线程知识点一、sleep()方法、wait()方法、yeild()方法、interrupt()方法、notify()、notifyAll()方法
1、sleep()方法:
sleep方法为Thread的静态方法;
sleep方法的作用是让线程休眠指定时间,在时间到达时自动恢复线程的执行;
sleep方法不会释放线程锁;

2、wait()方法:
wait方法是Object的方法;
任意一个对象都可以调用wait方法,调用wait方法会将调用者的线程挂起,使该线程进入一个叫waitSet 的等待区域,直到其他线程调用同一个对象的notify

方法才会重新激活调用者;
当wait方法被调用时,它会释放它所占用的锁标记,从而使线程所在对象中的synchronize数据可以被别的线程所使用,
所以wait()方法必须在同步块中使用,notify()和notifyAll()方法都会对对象的“锁标记”进行修改,所以都需要在同步块中进行调用,
如果不在同步块中调用,虽然可以编辑通过,但是运行时会报IllegalMonitorStateException(非法的监控状态异常);

3、yeild()方法:
yeild()方法表示停止当前线程,使该线程进入可执行状态,让同等优先级的线程运行,如果没有同等优先级的线程,那么yeild()方法不
会起作用;
4、notify()和nofityAll()方法;
notify()会通知一个处在wait()状态的线程;如果有多个线程处在wait状态,他会随机唤醒其中一个;
notifyAll()会通知过所有处在wait()状态的线程,具体执行哪一个线程,根据优先级而定;
二、java线程的状态
java线程有四种状态:产生、就绪、执行、阻塞、死亡
产生:线程被创建,但是未启动(未调用start())
就绪:线程被启动(调用start()),处于可执行状态,等待CPU的调度;
执行:线程正常的运行状态;
死亡:一个线程正常执行结束;
阻塞:
(1)、等待阻塞:运行的线程执行wait()方法,jvm会把该线程放入waitSet线程池(释放锁);
(2)、同步阻塞(死锁):运行的线程在获取其他对象的同步锁是,该对象的同步锁被别的线程锁占用,则jvm会将该线程放入线程池中;
(3)、其他阻塞:运行的线程执行sleep方法或者执行t.join()方法,被别的线程打断,jvm把该线程置为阻塞状态,当sleep超时或者join线程结

束时线程重新进入就绪状态
三、java实现多线程的方法:继承Thread类,实现runnable接口,实现Callable接口
1、继承Thread类:

public class MyThread extends Thread {  
      public void run() {  
       System.out.println("MyThread.run()");  
      }  
    }  
    MyThread myThread1 = new MyThread();  
    myThread1.start();

2、实现Runnable接口:

public class MyThread immplements Runnable {
        public void run(){
            sysout.out.println("MyThread.run()");
        }
    }
    MyThread runThread = new MyThread();
    Thread runThread = new Thread(runThread,"");
    runThread.start();

3、实现Callable接口,通过FutureTask包装器创建Thread线程

优缺点:
1)、继承Thread类为单继承,实现Runnable方法为多实现,所以在灵活性上来说,使用实现Runnable方法更灵活;
2)、通过实现Runnable接口的方式可以实现多线程内的资源共享;
3)、增加代码的健壮性,代码可以被多个线程共享,代码和数据独立;
4)、线程池只能放实现Runnable或callable类的线程,不能直接放入继承Thread类的线程;

四、线程调度
1、调整现场优先级:Java线程有优先级,优先级高的线程获得较多的运行机会(运行时间);
static int Max_priority 线程可以具有的最高优先级,值为10;
static int MIN_PRIORIYT 线程可以具有的最低优先级,值为1;
static int NORM_PRIORITY 分配给线程的默认优先级,值为5;
Thread类的setPriority()和getPriority()方法分别用来设置和获取线程的优先级;
2、线程睡眠:Thread.sleep(long millins)使线程转到阻塞状态;
3、线程等待:Object.wait()方法,释放线程锁,使线程进入等待状态,直到被其他线程唤醒(notify()和notifyAll());
4、线程让步:Thread.yeild()方法暂停当前正在执行的线程,使其进入等待执行状态,把执行机会让给相同优先级或更高优先级的线程,如果没有较高优先级或相同优先级的线程,该线程会继续执行;

5、线程加入:join()方法,在当前线程中调用另一个线程的join()方法,则当前线程转入阻塞状态,知道另一个进程运行结束,当前线程再有阻塞状态转为就绪状态;

五、线程类的一些常用方法:
1)、sleep():强迫一个线程睡眠N毫秒;
2)、isAlive():判断一个线程是否存活;
3)、join():线程插队;
4)、activeCount():程序中活跃的线程数;
5)、enumerate():枚举程序中的线程;
6)、currentThread():得到当前线程;
7)、isDeamon():一个线程是否为守护线程;
8)、setName():为线程设置一个名字;
9)、wait():线程等待;
10)、notify():唤醒一个线程;
11)、setPriority():设置一个线程的优先级;

六:线程同步
线程同步主要使用synchronized关键字;具体有两种实现方式:1、作为关键字修饰类中一个方法;2、修饰方法中的一块区域(代码);
1、把synchronized当做方法(函数)的修饰符:

public class Name{//类名为Name
    //getName方法
    public synchronized void getName(){
        system.out.println(“123”);
    }
}

类Name 有两个实例对象n1和n2,此时有两个线程t1和t2;n1在线程t1中执行getName()方法(获得这个方法的锁),那么n1就不能在线程t2中执行getName(

)方法了,但是n2可以在t1线程中执行getName()方法,同理n2 不能同时在t2线程中执行getName()方法;所以说实际上synchronized锁的是getName()

这个方法的对象(n1和n2),而不是锁的这个方法,这个需要理解;
2、同步块,实例代码如下:

public void getName(Object o){
        synchronized(o){
            //TODO
        }
    }

这里表示锁住这个变量o;
这里做一个线程安全的单例模式

public class Car{
  //构造方法私有化
  private Car();
  //创建一个静态的私有的空的常量car
  private static Car car = null;
  //对外开放一个静态的共有的方法用来获取实例
  public static getInstance(){
    if(car  == null){
      synchronized(Car.getClass()){
        if(car  == null){
            car = new Car();
        }
           }        
     }
    return car;
    }
}





4 个回复

倒序浏览
收藏
回复 使用道具 举报
很详细啊
回复 使用道具 举报
好传送,已收藏
回复 使用道具 举报
很详细吧
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马