JAVA线程

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

线程启动

1.利用Thread类的子类

public class PrintThread extend Thread {

private String message;

public PrintThread(String message) {

this.message = message;

}

Public void run() {

for(int i=0; i<1000; i++) {

System.out.println(message);

}

}

}

public class Main {

public static void main(String[] args) {

new PrintThread(“Good!”).start();

new PrintThread(“Nice!”).start();

}

}

注:调用的start()方法后,线程才开始运行,即调用run()方法2.利用Runnable接口

已实现Runnable接口的类必须实现run()方法

public class Printer implements Runnable {

private String message;

public Printer() {

this.message = message;

}

public void run() {

for(int i=0; i<10000; i++) {

System.out.println(message);

}

}

}

public class Main {

public static void main(String[] args) {

new Thread(new Printer(“Good!”)).start();

new Thread(new Printer(“Nice!”)).start();

}

}

注:不管使用那种方法,都需要调用start()方法启动线程…

线程暂时的停止

public class Mian {

public static void main(String[] args) {

for(int i=0; i<10000; i++) {

System.out.println(“Good!”);

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

}

}

}

}//每隔一秒输出一次

sleep()方法的调用被放在try-catch里面,这是因为sleep()方法可能抛出一个InterrupteException异常,InterrupteException时用在取消线程处理时的异常。

补充说明:利用sleep()方法所设置的时间并不是很精密,所以不太适合在实时的控制方面。若利用一下的语法结构,则可以ns(10-9s)为单位设置停止

时间。

Thread.sleep(ms, ns);

不过,一般的java处理系统并不需要用到这么精密的控制方式。事

实上,控制的精密度有多高有java处理系统而定。

欲执行wait()方法,线程必须获取锁定(这是规则)

wait、notify、notifyAll三者确实不是Thread类固有的方法。不过,因为Object 类时Java所有类的祖先类,所以wait、notify、notifyAll也是Thread类的方法。原子操作

synchronized方法同时只有一个线程可以执行。当一个线程正在执行synchronized方法时,其他线程不能进入这个方法。也就是这个synchronized方法所进行的操作,从多线程的角度来看,是“原子的操作(atomic poeration)”。atom是物理学中的“原子”的意思,本意是“不可分割的东西”。

long与double并不是原子的。

其实,java语言规格中,一开始就定义了一些原子操作,例如,char、int这些基本类型(primitive type)的赋值与引用操作时原子的。另外,对象引用类型(reference type)的赋值与引用操作也是原子的。因为本来就是定义成不可分割,就算没有加上synchronized,也不会被分割。

例:不如这里有一个int类型的字段n,而某个线程进行n=123;这样的赋值操作,而前后也有别的线程进行:n=456;这样的操作。这时最后的值不是123就是456,并不用担心两个值的位模式会混合在一起。

笔者刚刚说基本类型的指定、引用操作不可分割,但其实是有例外的。java 的语言规格上,long与double的指定、引用操作并非不可分割。

例如long类型进行上面n的赋值操作,操作之后的结果也许时123l、456l、0l,甚至出现31415986l,当然,这里所说的知识“java语言规格”而已。实际上大部分的java执行环境都将在long与double当作原子来操作的。但这里也只能说时部分java执行环境的实现就是了。

要在线程间共享long或double的字段时,必须在synchronized中操作,或时申明成volatile.(volatile该关键字的含义代表不可分割)

Immutable(不可改变) pattern

1.何时使用(适用性)

·当实例产生后,状态不在变化时

所谓实例的状态,是由字段的值所决定的,所以将字段设置成final,并且不要定义setter方法则是重点所在(所谓setter方法是指类用来改变字段值的方法的总称)。

然而,这样还是不够的。就算字段都是final,也没有setter方法,还是有可能定义出非Immutable的类。因为就算字段的值不会改变,字段所属的实例还是有可能改变。

·实例需要共享,而且访问很频繁时

使用Immutable的优点,在于“不需要使用synchronized保护”。不需要使用synchronized来保护最大的优点就是可在不丧失安全性与生命性的前提下,提高程序的执行性能。若实例有多数线程共享,而且访问可能会很频繁时,Immutable Pattern就能发挥极大的优点。省下synchronized执行时多出的时间。

·看到synchronized要想在保护的是什么

·线程的合作要想“放在中间的东西”

·线程的互斥要想“应该保护的东西”

sl eep方法与interrupt方法

以sleep方法为例,接下来我们要考虑的是如何取消。

线程Alice像下面这样,使用sleep线程暂停着。

sleep(604800000);

相关文档
最新文档