什么代码是始终为线程安全的、是不需要同步的。如下:
1)常量始终是线程安全的,因为只存在读操作。
2)对构造器的访问(new 操作)是线程安全的,因为每次都新建一个实例,不会访问共享的资源。
3)最重要的是:局部变量是线程安全的。因为每执行一个方法,都会在独立的空间创建局部变量,它不是共享的资源。局部变量包括方法的参数变量。
struts2本身就是多实例单线程的,所以可以说 本身就是线程安全的。
struts1则是单实例多线程的,所以必须要注意线程的安全性。struts user guide里有:
Only Use Local Variables - The most important principle that aids in thread-safe coding is to use only local variables, not instance variables , in your Action class.
译:只使用用局部变量。--编写线程安全的代码最重要的原则就是,在Action类中只使用局部变量,不使用实例变量。
所以相对来说,struts1 要多使用局部变量,而struts2使用 实例变量则不会产生不安全的结果。
在java中要想实现多线程,有两种手段,一种是继续Thread类,另外一种是实现Runable接口。
虽然我们调用的是start()方法,但是实际上调用的还是run()方法的主体。
那么:为什么我们不能直接调用run()方法呢?
我的理解是:线程的运行需要本地操作系统的支持。
start方法重复调用的话,会出现java.lang.IllegalThreadStateException异常
关于选择继承Thread还是实现Runnable接口?
实现Runnable接口比继承Thread类所具有的优势:
1)适合多个相同的程序代码的线程去处理同一个资源
2)可以避免java中的单继承的限制
3)增加程序的健壮性,代码可以被多个线程共享,代码和数据独立。
class MyThread implements Runnable{
private int ticket = 5; //5张票
public void run() {
for (int i=0; i<=20; i++) {
if (this.ticket > 0) {
System.out.println(Thread.currentThread().getName()+ "正在卖票"+this.ticket--);
}
}
}
}
public class lzwCode {
public static void main(String [] args) {
MyThread my = new MyThread();
new Thread(my, "1号窗口").start();
new Thread(my, "2号窗口").start();
new Thread(my, "3号窗口").start();
}
}
join():等待该线程终止。package thread;
class Boil implements Runnable{
@Override
public void run() {
try {
System.out.println("Begin to boil water");
Thread.sleep(10000);
System.out.println("End to boil water");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public class Bath implements Runnable{
public void shower() {
System.out.println("Begin to take a shower");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("End to take a shower");
}
public void prepare() {
System.out.println("Begin to prepare");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("End to prepare");
}
@Override
public void run() {
Thread b = new Thread(new Boil());
b.start();
prepare();
try {
b.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
shower();
}
public static void main(String args[]) {
Bath bath = new Bath();
new Thread(bath).start();
}
}
interrupt()
setDaemon()
setPriority()
yield()