JAVA线程
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 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);