CoreJava第10章:多线程

原文:http://blog.csdn.net/qjyong/archive/2009/09/14/4552701.aspx
1.
进程:正在运行程序
线程:程序中某条执行路径.
多进程:OS允许同时执行多程序.
多线程:程序允许同时执行多线程.

进程:有独立数据空间,切换效率低.
线程:共享进程数据空间,切换效率高.

2.创建线程
1)Runnable (推荐)
2)继承Thread

单cpu没有真正意义的执行多线程,cpu采用分时间片或抢占模式执行线程.
一个时刻只有一个执行线程,轮换时间短(可认为并发).

a)抢占式:获取分配时间片,激活线程,用完后以优先级抢占(优先级确定)
b)手机:协作式,不分时间片,yield,阻塞,等待才失去控制

3.jdk1.5以后定义为6种状态,(getState())
  1) NEW
  2) RUNNABLE(start后处于可运行,不一定正在运行)
  3) TERMINATED
  4) BLOCKED
  5) WAITING
  6) TIMED_WAITING

3.1阻塞的切换
a)试图获取内部对象锁,被其他占用,该线程阻塞(索取资源) blocked
b)等待一个线程通知调度器一个条件(系统安排),等待waiting
Object.wait Thread.join java.util.concurrent.Lock
java.util.concurrent.Condition

c)超时参数,调用进入time waiting,将保持超时期满或接收到通知
Thread.sleep
Object.wait Thread.join
java.util.concurrent.Lock.tryLock
java.util.concurrent.Condition.await

3.2终止(stop过时)
a)正常run接收
b)没有捕获异常

4.调度
sleep yield join(等待终止进程) wait notify() notifyAll()

5.中断
1)run正常结束
2)在sleep(),用interrupt()抛出异常
3)抛出异常

6.优先级(1-10) 默认5 NORM_PRIORITY

7.同步

8.其他线程获得机会
a)AWT的事件分派线程将一直并行运行,处理用户事件
b)比较耗时的任务应使用独立线程

9.每个任务占用一个线程,不推荐,推荐线程池

10.run执行同一线程,start(启动新线程,执行run)

11.中断线程 执行run最后一句,返回,或出未捕获异常
Thread.currentThread.isInterrupted 判断中断
b)阻塞线程(sleep,wait)线程无法检测中断,调用interrupt会被InterruptException中断
(阻塞I/O不能中断)
c)先interrupt后sleep也会抛出InterruptException中断
d)可自定义中断处理方式,不一定终止

12.isInterrupted实例方法 interrupted static方法会清楚中断状态

13.InterruptException中断处理
a) catch中中断 Thread.currentThread().interrupt();
b)抛出

public class BallTest {
	public static void main(String[] args) {

		EventQueue.invokeLater(new Runnable() {// EventQueue
					public void run() {
						JFrame frame = new BounceFrame();// frame
						frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
						frame.setVisible(true);
					}
				});
	}
}

class BounceFrame extends JFrame {

	private static final long serialVersionUID = 1L;
	private BallComponent comp;
	public static final int DEFAULT_WIDTH = 450;
	public static final int DEFAULT_HEIGHT = 350;
	public static final int STEPS = 1000;
	public static final int DELAY = 30;

	public BounceFrame() {
		setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
		setTitle("Bounce");
		comp = new BallComponent();// component
		add(comp, BorderLayout.CENTER);

		Panel buttonPanel = new Panel();// panel
		addButton(buttonPanel, "Start", new ActionListener() {// button
					public void actionPerformed(ActionEvent e) {
						addBall();// 事件监听
					}
				});

		addButton(buttonPanel, "Close", new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				System.exit(0);// 关闭
			}
		});
		add(buttonPanel, BorderLayout.SOUTH);
	}

	/**
	 * 添加按钮
	 * 
	 * @param buttonPanel
	 * @param string
	 * @param actionListener
	 */
	public void addButton(Container c, String title, ActionListener actionListener) {
		JButton button = new JButton(title);
		c.add(button);
		button.addActionListener(actionListener);
	}

	/**
	 * 添加balls
	 * 
	 */
	protected void addBall() {
		final Ball ball = new Ball();
		comp.add(ball);
		Thread t = new Thread(new Runnable() {
			public void run() {
				for (int i = 1; i <= STEPS; i++) {
					ball.move(comp.getBounds());
					comp.paint(comp.getGraphics());// 一般调用awt的repaint,然而addBall完全掌握控制权
					try {
						Thread.sleep(DELAY);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}// 抛出InterruptedException 中断异常
				}
			}
		});
		t.start();
	}
}

class Ball {

	private static final int XSIZE = 15;
	private static final int YSIZE = 15;
	private double x = 0;
	private double y = 0;
	private double dx = 1;
	private double dy = 1;

	public Ellipse2D getShape() {
		return new Ellipse2D.Double(x, y, XSIZE, YSIZE);
	}

	/**
	 * @param bounds
	 */
	public void move(Rectangle bounds) {
		x += dx;
		y += dy;
		if (x < bounds.getMinX()) {
			x = bounds.getMinX();
			dx = -dx;
		}
		if (x + XSIZE >= bounds.getMaxX()) {
			x = bounds.getMaxX() - XSIZE;
			dx = -dx;
		}
		if (y < bounds.getMinY()) {
			y = bounds.getMinY();
			dy = -dy;
		}
		if (y + YSIZE >= bounds.getMaxY()) {
			y = bounds.getMaxY() - YSIZE;
			dy = -dy;
		}
	}

	public void mode(Rectangle2D bounds) {// ??

	}
}

class BallComponent extends JPanel {

	private ArrayList<Ball> balls = new ArrayList<Ball>();

	public void add(Ball b) {
		balls.add(b);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.swing.JComponent#paintComponent(java.awt.Graphics)
	 */
	@Override
	public void paintComponent(Graphics g) {
		super.paintComponent(g);
		for (Ball b : balls) {
			((Graphics2D) g).fill(b.getShape());// 绘制球
		}
	}

}


14.线程优先级 默认继承父类优先级
线程优先级依赖于系统(被映射) windows7个 linux在虚拟机被忽略

15.yield 静态方法,线程将让步

16.守护进程 t.setDaemon(true);为其他线程服务
a)只剩守护进程,虚拟机退出
b)守护进程永远不访问固定资源(文件,数据库),因为可能在任何时候中断
c)线程启动前调用

17.未捕获异常处理器,不被捕获的异常导致线程终止
1)将未捕获异常写到日志
static void setDefaultUncaughtExceptionHandler
setUncaughtExceptionHandler
2)未安装处理器的,处理器为ThreadGroup对象UncaughtExceptionHandler
a)如该组有父线程组,父线程组的方法调用
b)否则,Thread.getDefaultExceptionHandler非空,调用
c)否则,Throwable是ThreadDeath的实例,什么都不做
d)否则,线程名,Throwable栈被输出System.err


18.同步 race condition 竞争条件
javap -c -v Bank 

1) ReenttrantLock
ReenttrantLock(boolean) 带公平策略(偏爱等待长的,效率低)
private Lock bankLock=new ReenttrantLock();
mylock.lock();
try{

//
}finally{
  mylock.unlock();
}

a)同一锁对象,串行运行
b)不同锁对象,互不干扰
c)可重复获得已经持有的锁,锁有个持有计数

2)条件变量 保证操作的一致性(管理进入保护区,还不能运行的)
private Condition suf=bankLock.newCondition();
while(!){
suf.await();//等待锁 ,可能死锁,无人唤醒
}
suf.singalAll();//激活-可运行-调度-等待获得锁-返回继续执行(当出现有利条件时)
(,当锁可用,不能马上解除阻塞)
singal() 随机


a)只能有一个线程执行保护代码
b)条件对象管理进入保护区但还不能运行的Thread


3)synchronized 方法获得对象锁(只有一个条件 wait notifyAll--只能在同步块中
为Object的final方法)
a)静态同步方法被调用,对象锁被锁住,方法不能被调用
b)单一条件可能不够,获取锁不超时,不能中断企图获得锁线程

4)同步阻塞
synchronized(lock)
synchronized(account)//对象锁 account有内部锁,不被修改,不建议


19.监视器
a)只有私有域
b)其对象有相关锁
c)锁对所有方法加锁(调用前自动添加,后自动释放)
d)可有多个条件

e)synchronized声明方法
f)每个条件独立管理一个线程集
g)java每个对象有个内部的锁和条件

20.问题
a)多核同一地方存储值不同
b)内存存储值不同

锁机制
1)必要时候刷新本地缓冲
2)不能不正当的重新排序指令

内部锁对象锁重叠引起阻塞
1)可用volatile
private volatile boolean done;
2)AtomicBoolean 提供原子性(不用锁) java.util.concurrent.atomic

域安全
1)final
2)访问由公有锁保护
3)violate

jconsole

等待获得锁
a)myLock.lock()//可能获得锁的时候中断
myLock.tryLock();//若被中断抛出InterruptedException,打破死锁
lockInterruptibly //超时无限
b)awaitUninterruptibly//不可中断
等待超时,singal 中断







































你可能感兴趣的:(多线程,thread,.net,Blog,OS)