Java入门——同步与死锁

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java入门——同步与死锁相关的知识,希望对你有一定的参考价值。

Java入门——同步与死锁


 

同步

  解决资源共享的同步操作,可以使用同步代码块和同步方法两种方法完成。

 

 1 package Sep19;
 2 
 3 class MyThread implements Runnable{
 4     private int ticket=5;
 5     public void run(){//覆写run方法
 6         for(int i=0;i<100;i++){
 7             if (ticket>0){
 8                 try{
 9                     Thread.sleep(3000);
10                 }catch(InterruptedException e){
11                     e.printStackTrace();
12                 }
13                 System.out.println("卖票:ticket="+ticket--);
14             }
15         }
16     }
17 }
18 public class SyncDemo01{
19     public static void main(String[] args) {
20         MyThread mt=new MyThread();
21         Thread t1=new Thread(mt);
22         Thread t2=new Thread(mt);
23         Thread t3=new Thread(mt);
24         t1.start();
25         t2.start();
26         t3.start();
27     }
28 }
卖票:ticket=5
卖票:ticket=3
卖票:ticket=4
卖票:ticket=2
卖票:ticket=1
卖票:ticket=0

同步代码块

  在所需要同步的代码前加关键字:synchronized(同步对象){需要同步的代码;}

同步方法:

  可以使用synchronized关键字声明同步方法。


死锁

  过多的同步操作也可能产生死锁的现象,两个线程都在彼此等待对方的执行完成,这样,线程就会无法继续向下执行,从而造成了死锁的现象。


 

线程的经典案例——生产者与消费者

package Sep19;
class Info{
	private String name="李兴华";
	private String content="JAVA讲师";
	public void setName(String name) {
		this.name = name;
	}
	public void setContent(String content) {
		this.content = content;
	}
	public String getName() {
		return name;
	}
	public String getContent() {
		return content;
	}
}

class Producer implements Runnable{
	private Info info=null;
	public Producer(Info info){
		this.info=info;
	}
	public void run() {
		boolean flag=false;
		for (int i = 0; i < 50; i++) {
			if(flag){
				this.info.setName("李兴华");
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				this.info.setContent("JAVA讲师");
				flag=false;
			}else{
				this.info.setName("mldn");
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				this.info.setContent("www.mldn.java.com");
				flag=true;
			}
		}
	}
}

class Consumer implements Runnable{
	private Info info=null;
	public Consumer(Info info){
		this.info=info;
	}
	public void run() {
		for (int i = 0; i < 50; i++) {
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println(this.info.getName()+"------->"+this.info.getContent());
		}
	}
	
}
public class ThreadCaseDemo01 {
	public static void main(String[] args) {
		Info i=new Info();
		Producer p=new Producer(i);
		Consumer con=new Consumer(i);
		new Thread(p).start();
		new Thread(con).start();
	}
}

  

李兴华------->www.mldn.java.com
李兴华------->www.mldn.java.com
mldn------->JAVA讲师
mldn------->JAVA讲师
李兴华------->www.mldn.java.com
李兴华------->JAVA讲师
mldn------->www.mldn.java.com
mldn------->JAVA讲师
mldn------->www.mldn.java.com
mldn------->JAVA讲师
mldn------->www.mldn.java.com
mldn------->JAVA讲师
李兴华------->www.mldn.java.com
李兴华------->JAVA讲师
李兴华------->www.mldn.java.com
mldn------->JAVA讲师
mldn------->www.mldn.java.com
李兴华------->www.mldn.java.com
李兴华------->www.mldn.java.com
李兴华------->JAVA讲师
李兴华------->www.mldn.java.com
mldn------->JAVA讲师
李兴华------->www.mldn.java.com
mldn------->JAVA讲师
李兴华------->www.mldn.java.com
mldn------->JAVA讲师
mldn------->www.mldn.java.com
李兴华------->JAVA讲师
mldn------->www.mldn.java.com
mldn------->JAVA讲师
李兴华------->www.mldn.java.com
mldn------->JAVA讲师
mldn------->www.mldn.java.com
mldn------->JAVA讲师
李兴华------->www.mldn.java.com
mldn------->JAVA讲师
mldn------->www.mldn.java.com
李兴华------->JAVA讲师
mldn------->www.mldn.java.com
李兴华------->JAVA讲师
李兴华------->www.mldn.java.com
mldn------->JAVA讲师
李兴华------->www.mldn.java.com
mldn------->JAVA讲师
mldn------->www.mldn.java.com
mldn------->JAVA讲师
mldn------->www.mldn.java.com
mldn------->JAVA讲师
李兴华------->www.mldn.java.com
李兴华------->JAVA讲师

  本代码出现了重复生产和姓名内容不匹配的现象,需要加入同步,也就是说把setName和setContent设置为在同一个代码块中完成,解决其错位问题。利用Obeject类中等待唤醒机制,的解决错位问题。

package Sep19;
class Info{
	private String name="李兴华";
	private String content="JAVA讲师";
	private boolean flag=false; 
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getContent() {
		return content;
	}

	public void setContent(String content) {
		this.content = content;
	}

	public synchronized void set(String name,String content){
		if(!flag){
			try {
				super.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		this.setName(name);
		try {
			Thread.sleep(300);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		this.setContent(content);
		flag=false;
		super.notify();
	}
	
	public synchronized void get(){
		try {
			Thread.sleep(300);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println(this.getName()+"----->"+this.getContent());
		flag=false;
		super.notify();
	}
}

class Producer implements Runnable{
	private Info info=null;
	public Producer(Info info){
		this.info=info;
	}
	public void run() {
		boolean flag=false;
		for (int i = 0; i < 50; i++) {
			if(flag){
				
				this.info.set("李兴华","JAVA讲师");
				flag=false;
			}else{
				
				this.info.set("mldn","www.mldn.java.com");
				flag=true;
			}
		}
	}
}

class Consumer implements Runnable{
	private Info info=null;
	public Consumer(Info info){
		this.info=info;
	}
	public void run() {
		for (int i = 0; i < 50; i++) {
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			this.info.get();
		}
	}
	
}
public class ThreadCaseDemo01 {
	public static void main(String[] args) {
		Info i=new Info();
		Producer p=new Producer(i);
		Consumer con=new Consumer(i);
		new Thread(p).start();
		new Thread(con).start();
	}
}

  

李兴华----->JAVA讲师
mldn----->www.mldn.java.com
李兴华----->JAVA讲师
mldn----->www.mldn.java.com
李兴华----->JAVA讲师
mldn----->www.mldn.java.com
李兴华----->JAVA讲师
mldn----->www.mldn.java.com
李兴华----->JAVA讲师
mldn----->www.mldn.java.com
李兴华----->JAVA讲师
mldn----->www.mldn.java.com
李兴华----->JAVA讲师
mldn----->www.mldn.java.com
李兴华----->JAVA讲师
mldn----->www.mldn.java.com
李兴华----->JAVA讲师
mldn----->www.mldn.java.com
李兴华----->JAVA讲师
mldn----->www.mldn.java.com
李兴华----->JAVA讲师
mldn----->www.mldn.java.com
李兴华----->JAVA讲师
mldn----->www.mldn.java.com
李兴华----->JAVA讲师
mldn----->www.mldn.java.com
李兴华----->JAVA讲师
mldn----->www.mldn.java.com
李兴华----->JAVA讲师
mldn----->www.mldn.java.com
李兴华----->JAVA讲师
mldn----->www.mldn.java.com
mldn----->www.mldn.java.com
李兴华----->JAVA讲师
mldn----->www.mldn.java.com
李兴华----->JAVA讲师
mldn----->www.mldn.java.com
李兴华----->JAVA讲师
mldn----->www.mldn.java.com
李兴华----->JAVA讲师
mldn----->www.mldn.java.com
李兴华----->JAVA讲师
mldn----->www.mldn.java.com
李兴华----->JAVA讲师
mldn----->www.mldn.java.com
李兴华----->JAVA讲师
mldn----->www.mldn.java.com
李兴华----->JAVA讲师
mldn----->www.mldn.java.com
李兴华----->JAVA讲师

  

 

以上是关于Java入门——同步与死锁的主要内容,如果未能解决你的问题,请参考以下文章

Java中线程死锁问题

Java之线程,常用方法,线程同步,死锁

Java_线程同步和死锁

线程同步与死锁

4-5 《Java中多线程重点》——继承Thread实现Runnable死锁线程池Lambda表达式

java基础入门-多线程同步浅析-以银行转账为样例