我的理解:
同步就是顺序执行,异步就是可以并行执行;
多线程是实现异步操作的一种手段或方式;
网上通俗点的解释:
使用同步方法:做完饭,再烧水!
假如,做饭时间为3,烧水时间为2,使用同步方法,做饭时间就延续为5,之后你才可以开始另外的工作。
使用异步方法:开两个火(两个线程),一个烧水一个做饭。
IAsyncResult代表其中任意一个的完成结果。
IAsyncResult.Iscompleted其中一个完成!(应该是烧水先完成),你可以使用IAsyncResult.waithandle.waitone (等待做饭完成,使用做饭那个火来炒菜),当然也可以用烧水的火开始炒菜。
异步,是针对同步对比而言的。它可能是使用同一个线程,也可能是是使用另外一个线程,这由你使用的框架系统来决定。
例如别人封装了一个方法
1
|
public
void
abc(
int
parameter, Action<
string
> callback);
|
1
2
3
|
var a = 1;
abc(a, method1);
xyz();
|
异步要比多线程更加高级,它可以多线程实现,也可以单线程实现,因为它根本不纠结于底层。
为何要使用同步?
同步的5种方法:
package com.xhj.thread;
/**
* 线程同步的运用
*
* @author XIEHEJUN
*
*/
public class SynchronizedThread {
class Bank {
private int account = 100;
public int getAccount() {
return account;
}
/**
* 用同步方法实现
*
* @param money
*/
public synchronized void save(int money) {
account += money;
}
/**
* 用同步代码块实现
*
* @param money
*/
public void save1(int money) {
synchronized (this) {
account += money;
}
}
}
class NewThread implements Runnable {
private Bank bank;
public NewThread(Bank bank) {
this.bank = bank;
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
// bank.save1(10);
bank.save(10);
System.out.println(i + "账户余额为:" + bank.getAccount());
}
}
}
/**
* 建立线程,调用内部类
*/
public void useThread() {
Bank bank = new Bank();
NewThread new_thread = new NewThread(bank);
System.out.println("线程1");
Thread thread1 = new Thread(new_thread);
thread1.start();
System.out.println("线程2");
Thread thread2 = new Thread(new_thread);
thread2.start();
}
public static void main(String[] args) {
SynchronizedThread st = new SynchronizedThread();
st.useThread();
}
}
class Bank {
//需要同步的变量加上volatile
private volatile int account = 100;
public int getAccount() {
return account;
}
//这里不再需要synchronized
public void save(int money) {
account += money;
}
}
class Bank {
private int account = 100;
//需要声明这个锁
private Lock lock = new ReentrantLock();
public int getAccount() {
return account;
}
//这里不再需要synchronized
public void save(int money) {
lock.lock();
try{
account += money;
}finally{
lock.unlock();
}
}
}
public class Bank{
//使用ThreadLocal类管理共享变量account
private static ThreadLocal<Integer> account = new ThreadLocal<Integer>(){
@Override
protected Integer initialValue(){
return 100;
}
};
public void save(int money){
account.set(account.get()+money);
}
public int getAccount(){
return account.get();
}
}
-
public static void main(String[] args) { -
System.out.println("main BEGIN"); -
Host host = new Host(); -
Data data1 = host.request(10, 'A'); -
Data data2 = host.request(20, 'B'); -
Data data3 = host.request(30, 'C'); -
-
System.out.println("main otherJob BEGIN"); -
try { -
Thread.sleep(200); -
} catch (InterruptedException e) { -
} -
System.out.println("main otherJob END"); -
-
System.out.println("data1 = " + data1.getContent()); -
System.out.println("data2 = " + data2.getContent()); -
System.out.println("data3 = " + data3.getContent()); -
System.out.println("main END"); -
} - }
下面来看一下,顾客定蛋糕后,蛋糕店做了什么:
- public
class Host { -
public Data request(final int count, final char c) { -
System.out.println("request(" + count + ", " + c + ") BEGIN"); -
-
// (1) 建立FutureData的实体 -
final FutureData future = new FutureData(); -
-
// (2) 为了建立RealData的实体,启动新的线程 -
new Thread() { -
public void run() { -
//在匿名内部类中使用count、future、c。 -
RealData realdata = new RealData(count, c); -
future.setRealData(realdata); -
} -
}.start(); -
-
System.out.println("request(" + count + ", " + c + ") END"); -
-
// (3) 取回FutureData实体,作为传回值 -
return future; -
} - }
下面来看看蛋糕师傅是怎么做蛋糕的:
建立一个字符串,包含count个c字符,为了表现出犯法需要花费一些时间,使用了sleep。
-
private final String content; -
public RealData(int count, char c) { -
System.out.println("making RealData(" + count + ", " + c + ") BEGIN"); -
char[] buffer = new char[count]; -
for (int i = 0; i < count; i++) { -
buffer[i] = c; -
try { -
Thread.sleep(1000); -
} catch (InterruptedException e) { -
} -
} -
System.out.println("making RealData(" + count + ", " + c + ") END"); -
this.content = new String(buffer); -
} -
public String getContent() { -
return content; -
} - }
-
private RealData realdata = null; -
private boolean ready = false; -
-
public synchronized void setRealData(RealData realdata) { -
if (ready) { -
return; // 防止setRealData被调用两次以上。 -
} -
this.realdata = realdata; -
this.ready = true; -
notifyAll(); -
} -
public synchronized String getContent() { -
while (!ready) { -
try { -
wait(); -
} catch (InterruptedException e) { -
} -
} -
return realdata.getContent(); -
} - }
System.out.println("data1
-
try { -
wait(); -
} catch (InterruptedException e) { -
} - //等做好后才能取到
- return
realdata.getContent();
future.setRealData(realdata);