学习线程之前首先要理解什么是进程?什么是线程?
进程: 每个正在系统上运行的程序都是一个进程。
线程:每个进程包括多个线程。线程是一组指令的几何,或者是程序的特殊段,它可以在程序里独立执行。
多线程:在单个程序中同时运行多个线程完成工作,为多线程。
线程 Thread 程序继承Thread之后必须要重写run方法。
每一个进程都至少有一个主执行线程(main)。
在多线程中为保证安全,要考虑线程同步和防止死锁。当两个或多个线程同时等待对方释放资源的时候就会形成线程之间的死锁。为防止死锁的发生,需要通过同步来实现线程安全。
何为同步?通俗的讲就是让多个线程在不同的时间执行相同的任务。即同步不同时。
有同步,也有异步。异步的概念与同步相反,即在同一时间执行同一任务。即异步同时。
实现线程同步的方法:
1.使用同步块
synchronized(Object){
}
2.synchronized方法 只能用于实例化方法
3.同步锁Lock 用来锁代码的
Lock lc = new ReentrantLock();
lc.lock();
lc.unlock();
下面的例子说明了Lock 的用法
public class Main {
public static void main(String args[]) {
User user = new User();
Card c = new Card(user, 800);
Card c2 = new Card(user, 500);
c.start();
c2.start();
}
}
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* 银行账户
*
* @author Dream
*
*/
public class User {
int money;
Lock lc = new ReentrantLock();
public User() {
money = 1000;
}
/**
* 取钱的方法
*/
public void getMoney(int n) {
lc.lock();// 上锁
// 模拟机器的计算时间
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
money -= n;
System.out.println("取钱完成,剩余金额:" + money);
lc.unlock();// 解锁
}
}
/**
* 取钱的线程
*
* @author Dream
*
*/
public class Card extends Thread {
User user;// 账户
int n;
public Card(User user, int n) {
this.user = user;
this.n = n;
}
public void run() {
user.getMoney(n);
}
}
这是两张卡同时用一个账户取钱的例子。当两张卡同时取钱时,如果不加锁,两次取钱后剩余金额会出现200,500,-300,三种情况。加锁之后两次取钱之后剩余金额为-300。此例也可用synchronized同步。
线程中还有生产/消费者模式:
主要用到wait/notify方法 wait等待,notify结束等待。
还可用LinkedBlockingQueue,阻塞队列(同步队列) 其中take(),put(),方法内部已实现等待,接触等待的功能,可以直接调用,而不用考虑资源是否足够。