设为首页 加入收藏

TOP

Java多线程模式(一)
2014-11-24 02:56:01 来源: 作者: 【 】 浏览:1
Tags:Java 线程 模式

public class PrintThread extends Thread {
private String msg;
public PrintThread(String msg) {
this.msg = msg;
}
public void run() {
for(int i = 0; i < 10000; i++) {
System.out.print(msg);
}
}


public static void main(String[] args {
new PrintThread("Good!").start();
new PrintThread("Nice!").start();
}
}


在main()方法里,先建立PrintThread类的实例后,调用该实例的start()方法启动线程。建立“PrintThread类的实例”和“启动该实例所对应的线程”是两个完全不同的处理。即使已经建立了实例,仍然必须等到调用start()方法才会启动线程。主线程在main()方法里启动两个线程,因为main()方法会立即结束,所以主线程也会立即结束,不过整个程序还没有结束,一直要等到所有线程都已经结束,程序才会结束。不过这里不包括daemon thread。利用Runnable接口


Runnable接口是java.lang Package里的接口,声明方法如下:


public interface Runnable {public abstract void run();}已实现Runnable接口的类必须实现run()方法。



public class PrintThread implements Runnable {
private String msg;
public PrintThread(String msg) {
this.msg = msg;
}
public void run() {
for(int i = 0; i < 10000; i++) {
System.out.print(msg);
}
}


public static void main(String[] args {
new Thread(new PrintThread("Good!")).start();
new Thread(new PrintThread("Nice!")).start();
}
}


使用该模式来限制同时只让一个线程运行。先看一个不是使用该模式的多线程的例子,并非线程安全(Thread-safe)的Gate类:


public class Main {
public static void main(String[] args) {
System.out.println("Testing Gate, hit CTRC+C to exit.");
Gate gate = new Gate();
new UserThread(gate, "Alice", "Alaska").start();
new UserThread(gate, "Bobby", "Brazil").start();
new UserThread(gate, "Chris", "Canada").start();
}
}


public class Gate {
private int counter = 0;
private String name = "Nobody";
private String address = "Nowhere";
public void pass(String name, String address) {
this.counter++;
this.name = name;
this.address = address;
check();
}
public String toString() {
return "No. " + counter + " name: " + name + ", address: " + address;
}
private void check() {
if (name.charAt(0) != address.charAt(0)) {
System.out.println("******BROKEN*******" + toString());
}
}


public class UserThread extends Thread {
private final Gate gate;
private final String myname;
private final String myaddress;
public UserThread (Gate gate, String myname, String myaddress) {
this.gate = gate;
this.myname = myname;
this.myaddress =myaddress;
}
public void run() {
System.out.println(this.myname + "Begin");
while(true) {
gate.pass(this.myname,myaddress);
}
}
}
}


执行看看。


由于Gate类不是线程安全的,当多个线程对其的状态进行更改时,会出现与期望不符的结果。可以通过将Gate类改造成线程安全的类来解决这个问题。线程安全最简单的方法即是使用本模式,使同一时间只让一个线程执行。线程安全版的Gate类如下:


public class Gate {
private int counter = 0;
private String name = "Nobody";
private String address = "Nowhere";
public synchronized void pass(String name, String address) {
this.counter++;
this.name = name;
this.address = address;
check();
}
public synchronized String toString() {
return "No. " + counter + " name: " + name + ", address: " + address;
}
private void check() {
if (name.charAt(0) != address.charAt(0)) {
System.out.println("******BROKEN*******" + toString());
}
}
}


即在pass()方法和toString()方法前面加上synchronized关键字,这样Gate类就是线程安全的类了。synchronized锁扮演的角色就是对共享资源的保护。
Single Threaded Execution Pattern的参与者:
SharedResource(共享资源):在本例中Gate类(准确说是Gate类的实例)是这个SharedResource。SharedResource是可由多个线程访问的类。在该模式下,我们对unsafeMethod加以防护,限制同时只能有一个线程进行访问,在Java语言中,将unsafeMethod定义成synchronized方法,就可以实现这个目标。这个必须只让单线程执行的程序范围,我们称为临界区(critical section)
何时该适用Single Threaded Execution Pattern,当SharedResouce实例可能同时被多个线程访问的时候,并且SharedResource的状态可能变化的时候。
另外注意,使用Single Threaded Execution Pattern 时可能会发生死锁(deadlock)的危险。
性能问题,临界区的大小与执行性能直接相关。首先,获取锁定需要花费时间,其次,线程冲突时必须等待。所以,

首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇Maven assembly插件输出文件乱码.. 下一篇Java实现文件拷贝

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: