Runnable
步骤:
1.定义实现Runnable接口
2.覆盖Runnable接口的方法,将线程要运行的代码方法方法放到run方发中。
3.通过Thread类建立线程对象。
4.将Runnable接口的子类对象作为实际参数传递给Thread类的构造函数
为什么要讲Runnable接口的子类对象传递给Thread的构造方法。因为自定义的方法所属的对象是Runnable接口的子类对象。
5.调用Thread类的Start方法开启线程并调用Runnable接口子类方法run方法。
线程安全的共享代码块问题
目的:程序是否存在安全问题,如果有,如何解决:
如何找问题?
1.明确哪些代码是多线程运行代码
2.明确共享数据
3.明确多线程运行代码中哪些语句是操作共享数据的
class Bank{
private int sum;
public void add(int n){//自定义的方法所属的对象是Runnable接口的子类对象。
sum+=n;
System.out.println("sum="+sum);
}
}
class Cus implements Runnable{ //1.定义实现Runnable接口
private Bank bank = new Bank();
@Override
public void run() {//2.覆盖Runnable接口的方法,将线程要运行的代码方法方法放到run方发中
synchronized (bank) {
for(int x = 0;x<3;x++){
bank.add(100);
}
}
}
}
public class Demo1 {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Cus cus = new Cus();
//3.通过Thread类建立线程对象。
//4.将Runnable接口的子类对象作为实际参数传递给Thread类的构造函数
Thread t1 = new Thread(cus);
Thread t2 = new Thread(cus);
//5.调用Thread类的Start方法开启线程并调用Runnable接口子类方法run方法。
t1.start();
t2.start();
}
}
将synchronized加在方法中
class Bank{
private int sum;
public synchronized void add(int n) throws InterruptedException{
sum+=n;
Thread.sleep(1000);
System.out.println("sum="+sum);
}
}
class Cus implements Runnable{
private Bank bank = new Bank();
public void run(){
for(int i=0;i<3;i++){
try {
bank.add(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public class Demo2{
public static void main(String []args){
Cus cus = new Cus();
Thread t1 = new Thread(cus);
Thread t2 =new Thread(cus);
t1.start();
t2.start();
}
}