线程:线程是操作系统运行时的最小调度单位,它是进程的一个执行序列。
进程:进程是运行程序的实体。一个CPU一个进程,不可能出现一个CPU多个线程的情况。
程序:程序是一组指示计算机每一步动作的指令。
多线程是指:同时运行多个线程。
现在的计算机基本都是双核四核的CPU,而如果我们使用多线程,这个时候就可以充分的使用到双核四核带来的好处了。
多线程示例代码
先以接口Runnable来做例子:
/**
* 银行存钱取钱业务,多线程下,需要注意可能多个线程会操作一个对象,需要使用synchronized 锁住
* @Title: Account.java
* @Package: com.sunhuwh.thread
* @Description:
* @author: hu.sun
* @date: 2016年8月15日 上午11:49:55
* @version:
*/
public class Account {
String holderName;
float amount;
public Account(String holderName, float amount) {
this.holderName = holderName;
this.amount = amount;
}
public synchronized Account cunqian(float amount){
amount = this.amount + amount;
return new Account(holderName, amount);
}
public synchronized Account quqian(float amount){
amount = this.amount - amount;
return new Account(holderName, amount);
}
public float chaqian(){
return amount;
}
public String getHolderName() {
return holderName;
}
public float getAmount() {
return amount;
}
}
public class AccountTest implements Runnable{
private Account account;
public AccountTest (Account account){
this.account = account;
}
public void cunqian(){
account.cunqian(10000);
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(account.getHolderName()+"余额为:"+account.getAmount());
}
@Override
public void run() {
cunqian();
}
}
public class AccountTest2 implements Runnable{
private Account account;
public AccountTest2(Account account) {
this.account = account;
}
public void quqian(){
account.quqian(1000);
System.out.println(account.getHolderName()+"取了1000元,余额"+account.getAmount());
}
@Override
public void run() {
quqian();
}
}
public class AccountMain {
public static void main(String[] args) throws InterruptedException {
duoxiancheng();
//danxiancheng();
}
private static void danxiancheng() {
long preTime = System.currentTimeMillis();
Account account = new Account("sh", 10000);
AccountTest at = new AccountTest(account);
at.cunqian();
AccountTest2 at2 = new AccountTest2(account);
at2.quqian();
long currTime = System.currentTimeMillis();
System.out.println(currTime-preTime+"ms");
}
static void duoxiancheng(){
long preTime = System.currentTimeMillis();
Account account = new Account("sh", 10000);
AccountTest at = new AccountTest(account);
Thread t = new Thread(at);
t.start();
//t.join();//等待线程结束
AccountTest2 at2 = new AccountTest2(account);
Thread t2 = new Thread(at2);
t2.start();
System.out.println(t2.isAlive());
while(true){
if(!t2.isAlive()&&!t.isAlive()){
long currTime = System.currentTimeMillis();
System.out.println(currTime-preTime+"ms");
break;
}
}
}
}
下一个例子,是使用Executor来实现的:
import java.util.concurrent.Executor;
public class DirectExecutor implements Executor{
@Override
public void execute(Runnable command) {
command.run();
}
}
import java.util.concurrent.Executor;
public class ExecutorPerTaskExecutor implements Executor{
@Override
public void execute(Runnable command) {
new Thread(command).start();
}
}
public class ExecutorTest {
public static void main(String[] args) {
Account account = new Account("sh", 10000);
AccountTest rImpl = new AccountTest(account);
AccountTest2 rImpl2 = new AccountTest2(account);
DirectExecutor d = new DirectExecutor();
d.execute(rImpl);
d.execute(rImpl2);
ExecutorPerTaskExecutor exPerTaskExecutor = new ExecutorPerTaskExecutor();
exPerTaskExecutor.execute(rImpl);
exPerTaskExecutor.execute(rImpl2);
}
}
引用了上面Runnable的类。
需要注意,我们下面的例子,一个是使用的run方法,一个使用的start方法。
区别:
run方法执行了,但还是在主线程中。
start方法,无需等待run方法执行,就可以处理下面的代码。
start方法的过程:
启动一个线程,
线程就绪,
执行run方法,
run方法执行完毕,进程关掉。