一、继承Thread类实现多线程
1、第一种
public class Demo5 {
public static void main(String[] args) {
Demo5 demo5 = new Demo5();
Thread1 thread1 = demo5.new Thread1();
Thread2 thread2 = demo5.new Thread2();
thread1.start();
thread2.start();
}
class Thread1 extends Thread {
private int count = 0;
public void run() {
for(int i =0;i<100;i++){
count++;
System.out.println(this.getName()+" count:"+count);
}
}
}
class Thread2 extends Thread {
private int count = 0;
public void run() {
for(int i =0;i<100;i++){
count++;
System.out.println(this.getName()+" count:"+count);
}
}
}
}
在主类类中定义线程
2、
/**
* 利用循环创建对象使用线程
* @author Administrator
*
*/
public class Demo4 extends Thread{
private int threadId;
public Demo4(int id) {
this.threadId = id;
}
public void run() {
for (int i = 0; i < 100; ++i) {
System.out.println("Thread ID: " + this.threadId + " : " + i);
}
}
}
class ThreadDemo {
/**
* @param args
* @throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < 10; ++i) {
new Thread(new Demo4(i)).start();
Thread.sleep(1);
}
}
}
在主类之外定义一个线程
二、实现runnable 接口实现多线程
public class Demo6 implements Runnable {
private String name;
public Demo6(String name) {
this.name = name;
}
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("线程开始:" + this.name + ",i=" + i);
}
}
public static void main(String[] args) {
Demo6 mt1 = new Demo6("线程a");
Demo6 mt2 = new Demo6("线程b");
Demo6 mt3 = new Demo6("线程c");
Demo6 mt4 = new Demo6("线程d");
Demo6 mt5 = new Demo6("线程e");
new Thread(mt1).start();
new Thread(mt2).start();
new Thread(mt3).start();
new Thread(mt4).start();
new Thread(mt5).start();
}
}
可以看到多个线程在同时执行。
三、关于线程同步(一个经典的ATM的Demo)
你有一个银行账户,里面有5000元钱,这个银行账户可以通过银行卡和存折进行取款和存款,
假设我现在正在ATM机钱进行取款,通过查询,发现账户内有余额5000元,你现在取3000元,这个时候账户内应该还剩下2000元
但是在我做取款操作的同时,我媳妇拿着银行的存折在柜台进行取款操作,同样的步骤,查询--》取款.
问题在这个时候产生了,如果在我在ATM机这里的取款操作还没有进行完成(ATM处理中,但还没有完成),我媳妇在柜台做取款的时候仍然会查询到账户还有5000元,这个是时候也进行取钱,那么我这个银行的账户会取款两次,但是只扣了一次3000元,账户中会剩余2000元。
JAVA代码
public class GetMoneyTest {
public static void main(String[] args) {
Account account = new Account(5000);
GetMoneyRun runnable = new GetMoneyRun(account);
new Thread(runnable, "我").start();
new Thread(runnable, "我媳妇").start();
}
}
// 账户Mode
class Account {
private int money;
public Account(int money) {
super();
this.money = money;
}
public int getMoney() {
return money;
}
public void setMoney(int money) {
this.money = money;
}
}
// runnable类
class GetMoneyRun implements Runnable {
private Account account;
public GetMoneyRun(Account account) {
this.account = account;
}
public void run() {
if (account.getMoney() > 3000) {
System.out.println("账户有" + account.getMoney() + "元");
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
int lasetMoney = account.getMoney() - 3000;
account.setMoney(lasetMoney);
System.out.println(Thread.currentThread().getName() + "取出来了3000元"
+ "的账户还有" + account.getMoney() + "元");
} else {
System.out.println("余额不足3000 你账户只有" + account.getMoney()
+ "元,当前取款人为" + Thread.currentThread().getName());
}
}
}
打印结果如下
可以看到,由于有两个线程同时访问这个account对象,导致取钱发生的账户发生问题。当多个线程访问同一个数据的时候,非常容易引发问题。为了避免这样的事情发生,我们要保证线程同步互斥,所谓同步互斥就是:并发执行的多个线程在某一时间内只允许一个线程在执行以访问共享数据。
使用synchronized 关键词
修改后的代码
public class GetMoneyTest {
public static void main(String[] args) {
Account account = new Account(5000);
GetMoneyRun runnable = new GetMoneyRun(account);
new Thread(runnable, "我").start();
new Thread(runnable, "我媳妇").start();
}
}
// 账户Mode
class Account {
private int money;
public Account(int money) {
super();
this.money = money;
}
public int getMoney() {
return money;
}
public void setMoney(int money) {
this.money = money;
}
}
// runnable类
class GetMoneyRun implements Runnable {
private Account account;
public GetMoneyRun(Account account) {
this.account = account;
}
public void run() {
synchronized (account) {
if (account.getMoney() > 3000) {
System.out.println("账户有"
+ account.getMoney() + "元");
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
int lasetMoney = account.getMoney() - 3000;
account.setMoney(lasetMoney);
System.out.println(Thread.currentThread().getName()
+ "取出来了3000元" + "的账户还有" + account.getMoney() + "元");
} else {
System.out.println("余额不足3000 你账户只有"
+ account.getMoney() + "元,当前取款人为"+Thread.currentThread().getName());
}
}
}
}
最后运行出来的结果,只会有两种, 只是看两个线程谁先执行完成。谁后执行完成。
参考文章
http://blog.csdn.net/lonelyroamer/article/details/7956097 Java多线程(三)、线程同步