您的位置:首页 > 编程语言 > Java开发

Java学习提要——简述多线程的同步synchronized与死锁

2016-09-03 19:32 531 查看
同步,异步到底是什么,看下面的例子:

//正常输出
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 MyT
d417
hread();
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) ;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: