在java中有两种创建线程的方式,分别是继承Thread类和实现Runnable接口。用同一个实现了Ruannale接口的对象为参数创建多个线程时,多个线程共享该对象中的数据。这是一种实现线程间通信的方法。
线程可以分为前台线程和后台线程。后台线程又叫守护线程或者辅助线程,它是一种低级线程,无法阻止程序结束。并且在后台线程中启动的其他线程均为后台线程。
在需要批量处理线程时,可以使用线程组(ThreadGroup类),它在java.lang中实现。线程在创建时需指定其所在的线程组,不指定则被分配到默认线程组。
java线程的优先级从低到高分为 1~10 级,默认的线程优先级是5级,同时线程将继承父线程的优先级(父线程即是启动这个线程的线程)。优先级可以通过Thread类的成员方法setPriority()来改变。
java线程的执行顺序由优先级决定。同一优先级随机执行。同时Thread类还提供了一些线程控制方法。
start():启动一个线程
static sleep():使当前线程休眠一段时间,休眠时依旧持有锁
static yiled():挂起当前线程,交给其他同优先级的线程执行,直到所有同优先级线程执行完毕
join():例如 A.join() 挂起当前线程,直到A线程执行完毕
interrupt():例如 A.interrupt() 向线程A发送中断信号,在线程A中通过Thread.interrupted()来判断是否中断,然后决定后续操作。interrupt()方法同时还会把线程A从阻塞状态变为执行状态。
除了以上5个Thread类的方法,在Object类中还有三个方法可以用于线程控制。
wait():使当前线程进入等待状态,同时释放object锁
wait(long timeout):超时自动被唤醒
notify():随机唤醒一个在等待object锁的线程
notifyAll():唤醒所有在等待object锁的线程需要指出,使用这三个方法是,必须先获得object锁,否则会冲突并报错。
在不同的线程同时访问相同的资源时,非常容易出错,这时就需要互斥机制来发挥作用了。每个java对象都对应一个“互斥锁”标记,而锁锁定的都是对象。在java中实现互斥锁可以使用synchronized方法和synchronized块。
synchronized方法的语法是:
public synchronized void test(){方法体};
它锁定的对象是调用该方法的对象。
synchronized块的语法是:synchronized(obj){代码块};
它锁定的是obj对象。
synchronized修饰的部分称为临界区。临界区可以被看作是一个原子操作,即要么不执行,要么全部执行。但是其本质并非如此,应该说线程只有获得了被synchronized锁定的对象的锁时才能进入临界区,而进入临界区的线程要在临界区代码执行完毕后才会释放锁。