你的位置:首页 > Java教程

[Java教程]线程浅谈


一。线程的实现方式有两种:
    一种是继承Thread类,重写run()方法。这种方法有两种不足:1.由于Java是单继承的,所以当一个类继承了Thread类雨                                                                                                        后就不能继承其他的类了。
                                                                                                 2.线程内部重写了run()方法来定义任务导致了线程与任务                                                                                                        有一个强耦合关系,线程会变得重用性,灵活度非常低
    第二种是:继承Runable接口。
        calss RunnableTest implements Runnable{}
        RunnableTest r=new RunnableTest();
        Thread t=new Thread(r);
        t.start();
运用:(用匿名内部类来创建)
Thread t=new Thread(new Runnable(){
        public void run(){    实现代码}    
    });
 t.start();
 
结论:
    start()方法是将线程纳入到线程调度中来。当CPU给该线程分配下时间片段时,这时才自动调用run()方法来执行代码。
 
                    面试题:
    
   
    运行结果为pongping
结论:线程的启动必须用start()方法,若调用run()方法来启动。那么这里将不会启动一个线程,相当于简单调用了run方法
二。获取线程相关信息的API:
    1.获取当前线程对象:Thread t=Thread.currentThread();
    2.线程的id:    long id=t.getId();
    3.线程的名字:String name=t.getName();
    4.线程的优先级: int priority=t.getPriority();
 
三。线程的优先级:
    线程调度的工作不可控,对于线程而言:
        1.分配的时间片长短不可控制
        2.分配时间给哪个线程不可控。
    线程只能被动的被分配时间片段,而不能主动地要求获得时间片段。
    而设置线程的优先级可以最大程度地干预线程调度工作,理论上,线程优先级高的线程分配的时间片段次数多。
    设置: Thread t=new Thread(){ 重写run()方法};    t.setPriority(Thread.MIN_PRIORITY);
四。static void sleep(long ms)方法
    使运行当前方法的线程阻塞指定毫秒数。超时后,线程会再次回到runnable状态,等待被分配时间片段。 

Thread.sleep(5000);

   该方法不用创建线程,可以在任何方法中使用。

Thread.yield();

   //这个方法是让出当前线程的时间片段。也是静态方法

五。守护线程:(又名后台线程)

    默认创建出来的线程都是前台线程。后台线程是要通过方法来指定,使前台线程变为后台线程。
    后台线程和前台线程主要区别在:结束的时机。        当一个进程中的所有前台线程都结束时,进程结束,无论进程中的后台线程是否在运行都要强制结束。
    用法:t.setDaemon(true);
    注意:这个设置一定要在start()方法之前设置。

六。void join()方法

    该方法会堵塞调用该方法的线程。
    比如:a线程调用了b线程的join()方法,b.join()。那么a线程就进入了阻塞状态,知道b线程结束,a线程才会继续执行,相当于b线程在a线程中插入。执行到插入那里时,会执行b线程,b结束后,继续执行a线程。
 
                                    synchronized(同步锁)
前提:(多个线程看到的必须是同一个对象)
1.多线程并发安全问题
    由于线程切换的不确定和不可控,导致多个线程若操作同一资源的时候,可能出现严重问题,所以要向解决“各干各的”变为“排队干”,这个时候就用到了synchonized(同步锁)了。

2.方法用synchronized修饰

    当一个方法被synchronized修饰后,该方法被称作同步方法,不能被多个线程同时进入,上锁的对象是当前方法的所属对象。

3.用synchronized修饰代码块

    有效的缩小同步范围可以提高并发的效率。使用synchronized块来缩小范围。
    因为所有上锁的都是当前对象。所以这里需要指定上锁的对象,用synchronized(this){}来实现。给这段代码上锁。那么多个线程不能同时进入到这段代码中。

4.静态方法上使用synchronized

    当静态方法上使用synchronized后,这里上锁的对象就是当前类的类对象。就是Class的对象。无论在哪调用这个方法都不能同时进入该静态方法。(多个线程看到的是同一个对象)

5.互斥锁

   同一个对象中的两个或多个不同的synchronized对象

6.死锁

    多个对象