同步,异步到底是什么,看下面的例子:
//正常输出
class MyThread implements Runnable {
private int ticket = 5 ; //一共5张票
public void run() {
for(int x=0 ; x < 20 ; x++) {
if(this.ticket > 0) {
System.out.println(Thread.currentThread().getName() + " ticket = " + this.ticket--);
}
}
}
}
public class Nice {
public static void main(String args[]) {
MyThread mt = new MyThread();
new Thread(mt,"AAA").start();
new Thread(mt,"BBB").start();
new Thread(mt,"CCC").start();
new Thread(mt,"DDD").start();
}
}
//加入延迟,非正常输出
class MyThread implements Runnable {
private int ticket = 5 ; //一共5张票
public void run() {
for(int x=0 ; x < 20 ; x++) {
if(this.ticket > 0) {
try{
Thread.sleep(100);
}catch(InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " ticket = " + this.ticket--);
}
}
}
}
public class Nice {
public static void main(String args[]) throws Exception {
MyThread mt = new MyThread();
new Thread(mt,"AAA").start();
new Thread(mt,"BBB").start();
new Thread(mt,"CCC").start();
new Thread(mt,"DDD").start();
}
}
//输出出现了负数,这就是不同步的情况
说实话,这个缘由,我也说不太清楚,我就举个例子吧。。
把上面程序分为三步:
1.判断是否有票
2.休眠
3.修改票数比方,只有一张票了,取票三步为三重门,四个人来拿票,为四个线程,第一个过第一个门,还有票,进去了,但是第二道门要休眠,可以理解为住一晚上,第二、三、四个人也过第一门了,还有票,因为第一个人还没拿到票,票数还是一,剩下也是这样。第二天,第一个人醒了,过了第二门,去第三门拿了票,票数减一为零,但是第二、三、四个人此时都在第二门休息,由于他们进的时候都有票,等他们过了第二门的时候,第三门是要给人家票,于是继续减一减一就有了负数。。
那么,解决的方法就是,把上面的三重门,变成一个大房子,把三重门都放里面
意思就是,一个人进去,剩下的人不能进去,等待,等待这个人出来,再来判断有没有票,有票就进去。。
实现方法:
1.同步代码块
2.同步方法
例:
//同步块
class MyThread implements Runnable {
private int ticket = 5 ; //一共5张票
public void run() {
for(int x=0 ; x < 20 ; x++) {
synchronized(this) { //当前操作只允许一个对象进入
if(this.ticket > 0) {
try{
Thread.sleep(1000);
}catch(InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " ticket = " + this.ticket--);
}
}
}
}
}
public class Nice {
public static void main(String args[]) throws Exception {
MyThread mt = new MyThread();
new Thread(mt,"AAA").start();
new Thread(mt,"BBB").start();
new Thread(mt,"CCC").start();
new Thread(mt,"DDD").start();
}
}
//同步方法
class MyThread implements Runnable {
private int ticket = 5 ; //一共5张票
public void run() {
for(int x=0 ; x < 20 ; x++) {
this.sale(); //调用同步方法
}
}
public synchronized void sale() { //定义
if(this.ticket > 0) {
try{
Thread.sleep(1000);
}catch(InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " ticket = " + this.ticket--);
}
}
}
public class Nice {
public static void main(String args[]) throws Exception {
MyThread mt = new MyThread();
new Thread(mt,"AAA").start();
new Thread(mt,"BBB").start();
new Thread(mt,"CCC").start();
new Thread(mt,"DDD").start();
}
}
同步操作与异步操作相比,异步操作的执行速度要高于同步操作
但是同步操作数据的安全性较高,属于安全的线程操作
死锁就举个例子吧,没什么意义。
//死锁产生实例,程序本身没有意义,理解就好了
class A {
public synchronized void test(B b) {
System.out.println("你给我东西,我才给你钱");
b.get();
}
public synchronized void get() {
System.out.println("我得到东西,你得到钱");
}
}
class B {
public synchronized void test(A a) {
System.out.println("你给我钱,我才给你东西");
a.get();
}
public synchronized void get() {
System.out.println("我得到钱,你得到东西");
}
}
public class Nice implements Runnable { //主类
private static A a = new A();
private static B b = new B() ;
public static void main(String args[]) {
new Nice() ;
}
public Nice() {
new Thread(this).start();
b.test(a);
}
public void run() {
a.test(b) ;
}
}