多线程笔记

一、新建线程
线程是程序中的执行线程。Java 虚拟机允许应用程序并发地运行多个执行线程。
多线程程序在较低的层次上扩展了多任务的概念:一个程序同时执行多个任务。通常,每一个任务称为一个线程(thread),可以同时运行一个以上线程的程序成为多线程程序(multithreaded)。
当 Java 虚拟机启动时,通常都会有单个非守护线程(它通常会调用某个指定类的 main 方法)。Java 虚拟机会继续执行线程,直到下列任一情况出现时为止:
调用了 Runtime 类的 exit 方法,并且安全管理器允许退出操作发生。
非守护线程的所有线程都已停止运行,无论是通过从对 run 方法的调用中返回,还是通过抛出一个传播到 run 方法之外的异常。
创建新执行线程有两种方法。一种方法是将类声明为 Thread 的子类。该子类应重写 Thread 类的 run 方法。接下来可以分配并启动该子类的实例。例如,计算大于某一规定值的质数的线程可以写成:


class PrimeThread extends Thread {
long minPrime;
PrimeThread(long minPrime) {
this.minPrime = minPrime;
}

public void run() {
// compute primes larger than minPrime
. . .
}
}


然后,下列代码会创建并启动一个线程:


PrimeThread p = new PrimeThread(143);
p.start();


创建线程的另一种方法是声明实现 Runnable 接口的类。该类然后实现 run 方法。然后可以分配该类的实例,在创建 Thread 时作为一个参数来传递并启动。采用这种风格的同一个例子如下所示:


class PrimeRun implements Runnable {
long minPrime;
PrimeRun(long minPrime) {
this.minPrime = minPrime;
}

public void run() {
// compute primes larger than minPrime
. . .
}
}


然后,下列代码会创建并启动一个线程:


PrimeRun p = new PrimeRun(143);
new Thread(p).start();


每个线程都有一个标识名,多个线程可以同名。如果线程创建时没有指定标识名,就会为其生成一个新名称。

警告:不要调用Thread类或Runnable对象的run()方法。直接调用run()方法,只会执行同一个线程中的任务,而不会启动新线程。应该调用Thread.start()方法。这个方法将创建一个执行run()方法的新线程。

二、中断线程
1. Thread.stop, Thread.suspend, Thread.resume
和Runtime.runFinalizersOnExit 这些终止线程运行的方法已经被废弃,使用它们是极端不安全的!
现在,如果你要安全有效地终止一个线程,应该采用以下这些方法:
* 线程正常执行完毕,正常结束。
* 监视某些条件,结束线程的不间断运行。
* 捕获InterruptedException 运行时异常,中断当前线程。
摘自:[url=http://blog.csdn.net/shendl/archive/2007/12/18/1947453.aspx]JAVA中断线程的方法[/url]

2. 注意Thread.interrupt()方法并不会真正中断线程。但当在一个被阻塞的线程上调用interrupt()方法时,阻塞调用将会被InterruptedException异常中断。

package test;


public class 多线程 {
public static void main(String[] args) {
Thread t01 = new Thread(new MyRun());

/*
* 1. 不启动线程结果:
* false
* false
*
* 2. 启动线程结果:
* false
* true
*
* 3. MyRun.run()中调用Thread.sleep(10000);
* false
* 抛出异常: InterruptedException
*/
t01.start();

System.out.println(t01.isInterrupted());
t01.interrupt();
System.out.println(t01.isInterrupted());
}
}

class MyRun implements Runnable{
public void run() {
System.out.println(Thread.currentThread());

// try...catch...
// Thread.sleep(10000);
}
}



三、线程状态
1. New(新生)
2. Runable(可运行)
3. Blocked(被阻塞)
4. Waiting(等待)
5. Timed waiting(计时等待)
6. Terminated(被终止)


[img]http://dl.iteye.com/upload/attachment/154058/b5eab07d-3eac-3fdc-b458-483430ceb973.png[/img]


四、线程属性
1. 线程优先级
在Java 程序设计语言中,每一个线程都有一个优先级。但是,线程优先级是高度依赖于操作系统的。当虚拟机依赖于宿主机平台的线程实现机制时,Java线程的优先级被映射到宿主机的优先级上,优先级个数也许更多,也许更少。
使用void setPrority(int newPriority)设置线程优先级。
警告:如果确实要使用优先级,应该避免一个错误:如果有几个高优先级的线程没有进入非活动状态,低优先级的线程可能永远也不能执行。每当调度器决定运行一个新线程时,首先会在具有较高优先级的线程中进行选择,尽管这样会使低优先级的线程完全饿死。

2. 守护线程
可以在线程启动之前调用void setDaemon(true);将线程转换为守护线程(daemon thread)。当只剩下守护线程时,虚拟机就退出了。

3. 线程组
4. 处理未捕获异常的处理器

五、锁对象
1. java.util.concurrent.locks.Lock
2. java.util.concurrent.locks.ReentrantLock

注意Lock只能对同一对象的行为加锁,不同对象之间的Lock没有影响。


package test;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;


public class 多线程02 {
public static void main(String[] args) {
MyRun02 mr = new MyRun02();

// 三个线程中分别是不同MyRun02对象,所以Lock并没有起到相应的作用。
Thread t01 = new Thread(new MyRun02());
Thread t02 = new Thread(new MyRun02());
Thread t03 = new Thread(new MyRun02());

// 三个线程中分别是同一个MyRun02对象,所以Lock起到了相应的作用。
// Thread t01 = new Thread(mr);
// Thread t02 = new Thread(mr);
// Thread t03 = new Thread(mr);

t01.start();
t02.start();
t03.start();

}
}

class MyRun02 implements Runnable{
public void run() {
try{
for(int i = 0; i < 3; i++){
lock.lock();
System.out.println(Thread.currentThread());
Thread.sleep(1000);
lock.unlock();
}
}catch (InterruptedException e) {
e.printStackTrace();
}
}

private Lock lock = new ReentrantLock();
}


六、条件对象
1. java.util.concurrent.locks.Condition
七、synchronized
八、volatile
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值