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讲师

  

时间: 2024-12-14 11:21:40

Java入门——同步与死锁的相关文章

Java线程同步与死锁、生产者消费者模式以及任务调度等

一.Thread类基本信息方法 package Threadinfo; public class MyThread implements Runnable{ private boolean flag = true; private int num = 0; @Override public void run() { while(flag) { System.out.println(Thread.currentThread().getName()+"-->"+num++); } }

java中同步嵌套引起的死锁事例代码

/* 目的:自己写一个由于同步嵌套引起的死锁! 思路:多个线程在执行时,某一时刻,0-Thread绑定了LockA锁,1-Thread绑定了LockB锁! 当0-Thread要去绑定LockB锁时 和 1-Thread要去绑定LockA锁时都不能绑定,此时两个线程不能继续进行! */ class Ticket implements Runnable{ public boolean flag; Ticket(boolean flag){ this.flag = flag; } Ticket(){

java多线程(同步与死锁问题,生产者与消费者问题)

首先我们来看同步与死锁问题: 所谓死锁,就是A拥有banana,B拥有apple. A对B说:你把apple给我,我就把banana给你. B对A说:你把banana给我,我就把apple给你. 但是A和B都在等待对方的答复,那么这样最终的结果就是A得不到apple,B也得不到banana.这种死循环就是死锁. 于是我们可以模拟上面的描述,写出以下代码: 类A代表A这个人, public class A { public void say(){ System.out.println("A sai

Java多线程编程(三)线程的优先级、同步与死锁

线程的优先级: 线程的优先级分为三种,分别是: 1-MIN_PRIORITY 10-MAX_PRIORITY 5-NORM_PRIORITY 如果什么都不设置默认值是5 线程的优先级可以影响线程的执行顺序,当然这里指的是有可能影响,不会一定影响.在默认状态下(比如说主线程)它的默认值是5 具体代码演示: package com.yeqc.thread; class ThRun implements Runnable{ @Override public void run() { for(int i

多线程——线程同步,死锁

线程同步: 为什么需要同步 ①   线程同步是为了防止多个线程访问一个数据对象时,对数据造成破坏. ②   线程的同步是保证多线程安全访问竞争资源的一种手段. 同步和锁 ①   Java中每一个对象都有一个内置锁. ②   当程序运行到非静态的synchronized同步方法上时,自动获得与正在执行代码类的当前实例(this实例)有关的锁:当程序运行到synchronized同步代码块时,自动获得锁定对象的锁. ③   获得一个对象的锁也称为获取锁.锁定对象.在对象上锁定或在对象上同步.当程序运

(转) Java多线程同步与异步

Java线程 同步与异步 线程池1)多线程并发时,多个线程同时请求同一个资源,必然导致此资源的数据不安全,A线程修改了B线 程的处理的数据,而B线程又修改了A线程处理的数理.显然这是由于全局资源造成的,有时为了解 决此问题,优先考虑使用局部变量,退而求其次使用同步代码块,出于这样的安全考虑就必须牺牲 系统处理性能,加在多线程并发时资源挣夺最激烈的地方,这就实现了线程的同步机制 同步:A线程要请求某个资源,但是此资源正在被B线程使用中,因为同步机制存在,A线程请求 不到,怎么办,A线程只能等待下去

java入门了解06

1.进程 :     (一)正在执行的程序称作为一个进程. 进程负责了内存空间的划分. (二)问题: windows号称是多任务的操作系统,那么windows是同时运行多个应用程序吗? 从宏观的角度: windows确实是在同时运行多个应用程序. 从微观角度: cpu是做了一个快速切换执行的动作,由于速度态度,所以我感觉不到在切换 而已. 2.线程:     线程的优先级默认是5:    (一)线程在一个进程 中负责了代码的执行,就是进程中一个执行路径, (二)多线程: 在一个进程中有多个线程同

Zookeeper Api(java)入门与应用(转)

如何使用 Zookeeper 作为一个分布式的服务框架,主要用来解决分布式集群中应用系统的一致性问题,它能提供基于类似于文件系统的目录节点树方式的数据存储,但是 Zookeeper 并不是用来专门存储数据的,它的作用主要是用来维护和监控你存储的数据的状态变化.通过监控这些数据状态的变化,从而可以达到基于数据的集群管理,后面将会详细介绍 Zookeeper 能够解决的一些典型问题,这里先介绍一下,Zookeeper 的操作接口和简单使用示例. 常用接口列表 客户端要连接 Zookeeper 服务器

Java入门记(五):容器关系的梳理(下)——Map

注意:阅读本文及相关源码时,需要数据结构相关知识,包括:哈希表.链表.红黑树. Map是将键(key)映射到值(value)的对象.不同的映射不能包含相同的键:每个键最多只能映射到一个值.下图是常见Map的接口和实现.与Collection相比,继承关系简单不少. 一.Map接口和AbstractMap抽象类 Map接口除了增加映射.根据key获取value.判断映射中的key或value是否存在.删除映射的基本方法外,还包含了返回包含所有key的Set.包含所有value的collection