Trail: Essential Classes_Lesson: Concurrency1

每个线程或者实现Runnable接口再传递给Tread构造,或者直接继承Thread类

前者的优势在于,还可以继承其他的类

 

Thread.sleep让当前线程休眠一段时间,让步给其他线程或程序

指定的这个时间通常不太精确,另外会被interrupt()中断休眠

 

中断是说这个线程立即终止目前的工作,但要想正确使用,事先要保证这个线程会抛出中断异常

 

for (int i = 0; i < importantInfo.length; i++) {
    // Pause for 4 seconds
    try {
        Thread.sleep(4000);//调用的这个方法可以被中断,中断后立即返回
    } catch (InterruptedException e) {
        // We've been interrupted: no more messages.
        return;
    }
    // Print a message
    System.out.println(importantInfo[i]);
}
if (Thread.interrupted()) {//调用这个方法能查询是否被中断了,同时也清除中断状态
    throw new InterruptedException();//或者手动抛出然后捕获
}

isInterrupted不会清除中断状态

 

但任何线程一旦跑出了中断异常,自动解除中断状态

 

t.join();会让当前线程暂停,等待t线程结束后再恢复,如果t现在正在运行的话
public static void main(String args[])
        throws InterruptedException {

        // Delay, in milliseconds before
        // we interrupt MessageLoop
        // thread (default one hour).
        long patience = 1000 * 60 * 60;//等待的最长时间

        // If command line argument
        // present, gives patience
        // in seconds.
        if (args.length > 0) {
            try {
                patience = Long.parseLong(args[0]) * 1000;
            } catch (NumberFormatException e) {
                System.err.println("Argument must be an integer.");
                System.exit(1);
            }
        }

        threadMessage("Starting MessageLoop thread");
        long startTime = System.currentTimeMillis();
        Thread t = new Thread(new MessageLoop());
        t.start();

        threadMessage("Waiting for MessageLoop thread to finish");
        // loop until MessageLoop
        // thread exits
        while (t.isAlive()) {
            threadMessage("Still waiting...");
            // Wait maximum of 1 second
            // for MessageLoop thread
            // to finish.
            t.join(1000);
            if (((System.currentTimeMillis() - startTime) > patience)
                  && t.isAlive()) {
                threadMessage("Tired of waiting!");//超过之后
                t.interrupt();//强制中断
                // Shouldn't be long now
                // -- wait indefinitely
                t.join();
            }
        }
        threadMessage("Finally!");
    }
}

 

 

线程间通常通过共享字段来交流,但经常性发生问题,thread interferencememory consistency errors

happens-before关系能够保证某个语句写后的内容在另一个语句读之前就已发生:

1.同一个线程,前一个语句总是在后一个语句之前执行

2.调用另一个线程的Thread.start时,所有之前的语句都会在新线程之前执行

3.一个线程终止时由于另一个线程调用了Thread.join,则任何改变都对另一个线程可见

4.声明为volatile的字段,写总是在读之前

5.同步机制synchronization


一个对象上的同步方法不会被多次调用,而且一次调用的结果总是对下次调用可见

不能对构造方法声明同步,所以构造中如果调用了某个方法,小心多线程错误

声明为final的字段无需用同步方法访问,因为构造后是无法修改的



	public static void main(String[] args) throws InterruptedException {

		for (int i = 0; i < 10; i++) {
			System.out.print(i + ",");
		}
		System.out.println();

		new Thread(new Runnable() {
			public void run() {
				for (int i = 11; i < 20; i++) {
					System.out.print(i + ",");
				}
			}
		}).start();

	}


这个输出结果只会是:

 

0,1,2,3,4,5,6,7,8,9,
11,12,13,14,15,16,17,18,19,

你可能感兴趣的:(concurrency)