java中提供的线程模型方式
1)编写一个类去继承Thread,并重写run方法(线程要做的事情)
调用start方法来启动线程
2)编写一个类去实现Runnable接口,并重写Runnable接口中的run方法
接下来创建Thread类的对象并把Runnable接口的实现类作为参数传入
Thread类的构造方法,最终由Thread对象.start()方法来启动线程并执行
Runnable对象的run方法。
Thread和Runnable的用法对比
1)当一个类既要继承一个父类还要实现一个线程的话,使用Runnable方式
2)当多个线程共享同一份数据的时候可以推荐使用Runnable方式。
同步处理问题?
synchronized修饰方法,称之为同步方法,也就说此同步方法中的代码只能有一个线程去访问,此线程
一调用同步方法就获取了对象的唯一一把锁,其它线程想进入同步方法的话只能等持有对象锁的那个线
程释放锁,不然就一直排队等待。
synchronized修饰语句块,称之为同步块
也就说此同步块中的代码只能有一个线程去访问,此线程一调用同步块就获取了对象锁,其它线程想进
入同步块的话只能等持有对象锁的那个线程释放锁,不然就一直排队等待。
同步块更灵活。
死锁的原因往往是同步块中去嵌套了同步块,所以尽量比较同步块的嵌套。
//比较经典的例题:有一个山洞,多列火车都想穿过山洞,但同时只能一辆进入山洞。
//火车1进入山洞
//火车1开出山洞
....
//火车2进入山洞
public class BankDemo {
public static void main(String[] args) {
Bank bank = new Bank();
MoneyThread t1 = new MoneyThread(bank);// 柜面取款
t1.start();
MoneyThread t2 = new MoneyThread(bank);// ATM取款
t2.start();
}
}
class MoneyThread extends Thread {
private Bank bank;
public MoneyThread(Bank bank) {
this.bank = bank;
}
@Override
public void run() {
System.out.println("取钱:" + bank.getMoney(400));
}
}
class Bank {
private int money = 500;// 共享数据
// 银行取钱,返回取钱的数目
// 第二个线程排队等待对方释放锁
public int getMoney(int number) {
synchronized (Bank.class) {
// 同步块,括号中指的是对象,也就是说指定获取哪个对象的锁
if (number <= 0) {
return -1;// 取钱为负数
} else if (money < 0) {
return -2;// 账号的钱不能小于0
} else if (number - money > 0) {
return -3;// 取钱超过账号中的钱
} else {
//
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
money -= number;
System.out.println("余额:" + money);
}
return number;
}
}
}
1)编写一个类去继承Thread,并重写run方法(线程要做的事情)
调用start方法来启动线程
2)编写一个类去实现Runnable接口,并重写Runnable接口中的run方法
接下来创建Thread类的对象并把Runnable接口的实现类作为参数传入
Thread类的构造方法,最终由Thread对象.start()方法来启动线程并执行
Runnable对象的run方法。
Thread和Runnable的用法对比
1)当一个类既要继承一个父类还要实现一个线程的话,使用Runnable方式
2)当多个线程共享同一份数据的时候可以推荐使用Runnable方式。
同步处理问题?
synchronized修饰方法,称之为同步方法,也就说此同步方法中的代码只能有一个线程去访问,此线程
一调用同步方法就获取了对象的唯一一把锁,其它线程想进入同步方法的话只能等持有对象锁的那个线
程释放锁,不然就一直排队等待。
synchronized修饰语句块,称之为同步块
也就说此同步块中的代码只能有一个线程去访问,此线程一调用同步块就获取了对象锁,其它线程想进
入同步块的话只能等持有对象锁的那个线程释放锁,不然就一直排队等待。
同步块更灵活。
死锁的原因往往是同步块中去嵌套了同步块,所以尽量比较同步块的嵌套。
//比较经典的例题:有一个山洞,多列火车都想穿过山洞,但同时只能一辆进入山洞。
//火车1进入山洞
//火车1开出山洞
....
//火车2进入山洞
//火车2开出山洞
//取钱 (银行柜面取钱和ATM机取钱的例题)
public class BankDemo {
public static void main(String[] args) {
Bank bank = new Bank();
MoneyThread t1 = new MoneyThread(bank);// 柜面取款
t1.start();
MoneyThread t2 = new MoneyThread(bank);// ATM取款
t2.start();
}
}
class MoneyThread extends Thread {
private Bank bank;
public MoneyThread(Bank bank) {
this.bank = bank;
}
@Override
public void run() {
System.out.println("取钱:" + bank.getMoney(400));
}
}
class Bank {
private int money = 500;// 共享数据
// 银行取钱,返回取钱的数目
// 第二个线程排队等待对方释放锁
public int getMoney(int number) {
synchronized (Bank.class) {
// 同步块,括号中指的是对象,也就是说指定获取哪个对象的锁
if (number <= 0) {
return -1;// 取钱为负数
} else if (money < 0) {
return -2;// 账号的钱不能小于0
} else if (number - money > 0) {
return -3;// 取钱超过账号中的钱
} else {
//
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
money -= number;
System.out.println("余额:" + money);
}
return number;
}
}
}