Java线程的同步与死锁
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
*/
class TicketSeller{ int five=1,ten=0,twenty=0; public synchronized void sellTicket(int money){ try{ Thread.currentThread().sleep(2000); }catch(InterruptedException e){
} } } public void run() { //runnable接口后,可以用run覆写run了 oper(name, bs); } } class ThreadTest { public static void main(String args[]) throws InterruptedException { BlankSaving bs=new BlankSaving(); Operater o1=new Operater(bs,"husband"); Operater o2=new Operater(bs,"wife"); Thread t1=new Thread(o1); Thread t2=new Thread(o2);
*/ class BlankSaving {
private static int money = 8000; public void add(int i) {
money = money + i; System.out.println("存入" + i+"余额是"+money); } public void get(int i) { if (i > money) {
} 运行结果: 进入 T1 and wait 进入 T2 and notify be notified
(long1 vs longpo 转载请注明出处:/lfw2565295@126)
/* 线程调度规则: 1. 两个或两个以上线程都要修改一个对象,把执行修改的方法定义为同步,更行影响到只 读方法,也该同步 2.如果一个线程必须等待一个被同步的方法, 那么它应该在对象内部等待,而不是在外部 等待,它可以调用一个被同步的方法,并让这个方法调用wait() 3.每当一个方法改变某个对象的状态时,应该调用notifyAll()方法,这给等待队列的线 程提供机会来看一看执行环境是否发生改变 4.wait,notify,notifyAll都是Object类,而非Thread类,仔细检查每次执行wait() 方法都应有相应的notify或notifyAll,作用于相同对象。 java中每个类都有一个主线程,要执行一个程序,那么这个类中一定有 main方法,这个 main方法也是java class中的主线程
线程的调度: wait()等待 public final void wait() throws InterruptedException 让出 CPU资源,被唤醒后还需要排队等待 notify()唤醒 public final native void notify(); notifyAll()唤醒所有线程 public final native void notifyAll();
*/ class T1 extends Thread{
Object lock; public T1(Object o){
lock=o; } public void run(){
try{ synchronized(lock){ //如果lock改成this就错了, System.out.println("进入 T1 and wait"); lock.wait(); //对wait需要catch,直到其他线程进入同一监视器
t1.start();
t2.start(); Thread.currentThread().sleep(1000);
}
} 运行结果:(丈夫操作完了,妻子才可以操作,不加 synchronized 可能会乱序) husband存入1000余额是9000 husband存入1000余额是10000 husband存入1000余额是11000 husband存入1000余额是12000 husband存入1000余额是13000 wife取走1000余额是12000 wife取走1000余额是11000 wife取走1000余额是10000 wife取走1000余额是9000 wife取走1000余额是8000 wife取走1000余额是7000 wife取走1000余额是6000 wife取走1000余额是5000 wife取走1000余额是4000 wife取走1000余额是3000 wife取走1000余额是2000 wife取走1000余额是1000 wife取走1000余额是0 wife余额不足! wife余额不足! wife余额不足! wife余额不足! wife 余额不足!
synchronized(lock){ System.out.println("进入 T2 and notify"); lock.notify();
} } } class ThreadTest{ public static void main(String args[]){
int[] in=new int[0]; T1 t1=new T1(in); T2 t2=new T2(in); t1.start(); t2.start(); }
(long1 vs longpo 转载请注明出处:/lfw2565295@126)
/* 同步的机制虽然很方便 ,但可能导致死锁。 死锁是发生在线程间相互阻塞的现象。多个线程访问共享资源需要提供同步机制,但可能 出线线程永远被阻塞的现象。 当两个或多个线程等待一个不可能满足的条件时,会发生死锁 。 如果两个线程分别等待对方占有的一个资源,于是两者都不能执行而处于永远等待,产生死 锁。 这个需要程序员逻辑上谨慎,根据需要用多线程和同步,尽可能少的使用同步资源
下面程序使用了synchronized块来包装相关方法,和notify方法是Object类中的,并不在Thread类 创建new Object比较慢,改创建int[] in=new int[0],0长度数组充当锁高效 使用wait()就要有配对的notify()
Java线程的同步与死锁
/* java中线程并发将共同抢CPU资源,哪个抢到就运行,往往会有冲突,为了避免,引入线
程等待sleep() 还有可以使用join方法,当前线程等待调用该方法的线程结束后,再恢复执行,见下面例
子,A执行时,B.join后,A等B执行完后执行 当然还有可以setPriority, getPriority设置查看优先级 */
} } } } } class ThreadTest{ public static void main(String args[]){ JoinThread a=new JoinThread(); a.A.start();
a.B.start(); } } 运行结果: 我等预报员说完话再说 预报员说: 天气预报,多云转阴,有小雨,最高温度15C,最低温度5C 我开始说话:'我知道了,谢谢'
BlankSaving bs; public Operater(BlankSaving b, String s) {
name = s; bs = b; } public synchronized static void oper(String name, BlankSaving bs) { // 如果去掉synchronized可能会出错 if (name.equals("husband")) {
(long1 vs longpo 转载请注明出处:/lfw2565295@126)
/* java应用程序的多个线程共享同一进程的数据资源,多个用户线程在并发运行过程中可能 会同时访问具有敏感性的内容,或同时访问同一文件(变量) 且一个线程需要修改这个文件(变量)时,另一个也要修改,比如售票系统,同时出票。 线程的同步,实现对共享资源的一致性维护,保证一个进程中多个线程的协调工作,所以线 程的同步很重要。 java在共享内存变量方法前加synchronized修饰符,某个线程调用时,在结束之前,其 他线程不能运行该方法,只能等待它结束,其它的等待它结束释放 该同步方法返回之前,已处于同步方法引起的堵塞氛围要一直等到堵塞的原因消除(同步方 法返回),才再排队等待使用这个同步方法。 [modifier] synchronized returnType methodName([parameterList]){} [modifier] returnType methodName([parameterList]) 如: synchronized(this){}
并调用notify为止 System.out.println("be notified");
} }catch(InterruptedException e){
} } } class T2 extends Thread{ Object lock; public T2(Object o){
lock=o; } public void run(){
System.out.println("余额不足!"); } else {
money = money - i; System.out.println("取走" + i+"余额是"+money); } } public int showMoney() { return money; } } class Operater implements Runnable { String name;
class JoinThread implements Runnable{ Thread A,B; String[] content={"天气预报","多云转阴","有小雨","最高温度15C","最低
温度5C"}; JoinThread(){ A=new Thread(this); B=new Thread(this); B.setName("预报员"); } public void run(){ if(Thread.currentThread()==A){ System.out.println("我等"+B.getName()+"说完话再说"); try{ B.join(); //线程A开始等待B结束 }catch(InterruptedException e){ } System.out.println("\n我开始说话:\'我知道了,谢谢\'"); }else if(Thread.currentThread()==B){ System.out.println(B.getName()+"说:"); for(int i=0; i<content.length; i++){ if(i!=0) System.out.print(","); System.out.print(content[i]); try{ B.sleep(3000); }catch(InterruptedException e){
} } else {
try { for (int i = 0; i < 18; i++) { Thread.currentThread().sleep((long) (Math.random()
* 300)); System.out.print("wife"); bs.get(1000);
} } catch (InterruptedException e) {
try { for (int i = 0; i < 5; i++) { Thread.currentThread().sleep((long) (Math.random()
* 300)); System.out.print("husband"); bs.add(1000);
} } catch (InterruptedException e) {
class TicketSeller{ int five=1,ten=0,twenty=0; public synchronized void sellTicket(int money){ try{ Thread.currentThread().sleep(2000); }catch(InterruptedException e){
} } } public void run() { //runnable接口后,可以用run覆写run了 oper(name, bs); } } class ThreadTest { public static void main(String args[]) throws InterruptedException { BlankSaving bs=new BlankSaving(); Operater o1=new Operater(bs,"husband"); Operater o2=new Operater(bs,"wife"); Thread t1=new Thread(o1); Thread t2=new Thread(o2);
*/ class BlankSaving {
private static int money = 8000; public void add(int i) {
money = money + i; System.out.println("存入" + i+"余额是"+money); } public void get(int i) { if (i > money) {
} 运行结果: 进入 T1 and wait 进入 T2 and notify be notified
(long1 vs longpo 转载请注明出处:/lfw2565295@126)
/* 线程调度规则: 1. 两个或两个以上线程都要修改一个对象,把执行修改的方法定义为同步,更行影响到只 读方法,也该同步 2.如果一个线程必须等待一个被同步的方法, 那么它应该在对象内部等待,而不是在外部 等待,它可以调用一个被同步的方法,并让这个方法调用wait() 3.每当一个方法改变某个对象的状态时,应该调用notifyAll()方法,这给等待队列的线 程提供机会来看一看执行环境是否发生改变 4.wait,notify,notifyAll都是Object类,而非Thread类,仔细检查每次执行wait() 方法都应有相应的notify或notifyAll,作用于相同对象。 java中每个类都有一个主线程,要执行一个程序,那么这个类中一定有 main方法,这个 main方法也是java class中的主线程
线程的调度: wait()等待 public final void wait() throws InterruptedException 让出 CPU资源,被唤醒后还需要排队等待 notify()唤醒 public final native void notify(); notifyAll()唤醒所有线程 public final native void notifyAll();
*/ class T1 extends Thread{
Object lock; public T1(Object o){
lock=o; } public void run(){
try{ synchronized(lock){ //如果lock改成this就错了, System.out.println("进入 T1 and wait"); lock.wait(); //对wait需要catch,直到其他线程进入同一监视器
t1.start();
t2.start(); Thread.currentThread().sleep(1000);
}
} 运行结果:(丈夫操作完了,妻子才可以操作,不加 synchronized 可能会乱序) husband存入1000余额是9000 husband存入1000余额是10000 husband存入1000余额是11000 husband存入1000余额是12000 husband存入1000余额是13000 wife取走1000余额是12000 wife取走1000余额是11000 wife取走1000余额是10000 wife取走1000余额是9000 wife取走1000余额是8000 wife取走1000余额是7000 wife取走1000余额是6000 wife取走1000余额是5000 wife取走1000余额是4000 wife取走1000余额是3000 wife取走1000余额是2000 wife取走1000余额是1000 wife取走1000余额是0 wife余额不足! wife余额不足! wife余额不足! wife余额不足! wife 余额不足!
synchronized(lock){ System.out.println("进入 T2 and notify"); lock.notify();
} } } class ThreadTest{ public static void main(String args[]){
int[] in=new int[0]; T1 t1=new T1(in); T2 t2=new T2(in); t1.start(); t2.start(); }
(long1 vs longpo 转载请注明出处:/lfw2565295@126)
/* 同步的机制虽然很方便 ,但可能导致死锁。 死锁是发生在线程间相互阻塞的现象。多个线程访问共享资源需要提供同步机制,但可能 出线线程永远被阻塞的现象。 当两个或多个线程等待一个不可能满足的条件时,会发生死锁 。 如果两个线程分别等待对方占有的一个资源,于是两者都不能执行而处于永远等待,产生死 锁。 这个需要程序员逻辑上谨慎,根据需要用多线程和同步,尽可能少的使用同步资源
下面程序使用了synchronized块来包装相关方法,和notify方法是Object类中的,并不在Thread类 创建new Object比较慢,改创建int[] in=new int[0],0长度数组充当锁高效 使用wait()就要有配对的notify()
Java线程的同步与死锁
/* java中线程并发将共同抢CPU资源,哪个抢到就运行,往往会有冲突,为了避免,引入线
程等待sleep() 还有可以使用join方法,当前线程等待调用该方法的线程结束后,再恢复执行,见下面例
子,A执行时,B.join后,A等B执行完后执行 当然还有可以setPriority, getPriority设置查看优先级 */
} } } } } class ThreadTest{ public static void main(String args[]){ JoinThread a=new JoinThread(); a.A.start();
a.B.start(); } } 运行结果: 我等预报员说完话再说 预报员说: 天气预报,多云转阴,有小雨,最高温度15C,最低温度5C 我开始说话:'我知道了,谢谢'
BlankSaving bs; public Operater(BlankSaving b, String s) {
name = s; bs = b; } public synchronized static void oper(String name, BlankSaving bs) { // 如果去掉synchronized可能会出错 if (name.equals("husband")) {
(long1 vs longpo 转载请注明出处:/lfw2565295@126)
/* java应用程序的多个线程共享同一进程的数据资源,多个用户线程在并发运行过程中可能 会同时访问具有敏感性的内容,或同时访问同一文件(变量) 且一个线程需要修改这个文件(变量)时,另一个也要修改,比如售票系统,同时出票。 线程的同步,实现对共享资源的一致性维护,保证一个进程中多个线程的协调工作,所以线 程的同步很重要。 java在共享内存变量方法前加synchronized修饰符,某个线程调用时,在结束之前,其 他线程不能运行该方法,只能等待它结束,其它的等待它结束释放 该同步方法返回之前,已处于同步方法引起的堵塞氛围要一直等到堵塞的原因消除(同步方 法返回),才再排队等待使用这个同步方法。 [modifier] synchronized returnType methodName([parameterList]){} [modifier] returnType methodName([parameterList]) 如: synchronized(this){}
并调用notify为止 System.out.println("be notified");
} }catch(InterruptedException e){
} } } class T2 extends Thread{ Object lock; public T2(Object o){
lock=o; } public void run(){
System.out.println("余额不足!"); } else {
money = money - i; System.out.println("取走" + i+"余额是"+money); } } public int showMoney() { return money; } } class Operater implements Runnable { String name;
class JoinThread implements Runnable{ Thread A,B; String[] content={"天气预报","多云转阴","有小雨","最高温度15C","最低
温度5C"}; JoinThread(){ A=new Thread(this); B=new Thread(this); B.setName("预报员"); } public void run(){ if(Thread.currentThread()==A){ System.out.println("我等"+B.getName()+"说完话再说"); try{ B.join(); //线程A开始等待B结束 }catch(InterruptedException e){ } System.out.println("\n我开始说话:\'我知道了,谢谢\'"); }else if(Thread.currentThread()==B){ System.out.println(B.getName()+"说:"); for(int i=0; i<content.length; i++){ if(i!=0) System.out.print(","); System.out.print(content[i]); try{ B.sleep(3000); }catch(InterruptedException e){
} } else {
try { for (int i = 0; i < 18; i++) { Thread.currentThread().sleep((long) (Math.random()
* 300)); System.out.print("wife"); bs.get(1000);
} } catch (InterruptedException e) {
try { for (int i = 0; i < 5; i++) { Thread.currentThread().sleep((long) (Math.random()
* 300)); System.out.print("husband"); bs.add(1000);
} } catch (InterruptedException e) {