2021-02-19Java学习记录

Java基础(简答)- - - - - -多线程(修饰同步方法? stop()和suspend()方法为何不推荐使用?)

  • stop(),是因为它不安全。它会解除由线程获取的所有锁定,而且如果对象处于一种不连贯状态,那么其他线程能在那种状态下检查和修改它们。结果很难检查出真正的问题所在。
  • suspend()方法容易发生死锁。调用suspend()的时候,目标线程会停下来,但却仍然持有在这之前获得的锁定。此时,其他任何线程都不能访问锁定的资源,除非被"挂起"的线程恢复运行。对任何线程来说,如果它们想恢复目标线程,同时又试图使用任何一个锁定的资源,就会造成死锁。所以不应该使用suspend(),而应在自己的Thread类中置入一个标志,指出线程应该活动还是挂起。若标志指出线程应该挂起,便用wait()命其进入等待状态。若标志指出线程应当恢复,则用一个notify()重新启动线程。

Java基础(简答)- - - - - -多线程(sleep() 和 wait() 有什么区别? )

  • sleep是线程类(Thread)的方法,导致此线程暂停执行指定时间,给执行机会给其他线程,但是监控状态依然保持,到时后会自动恢复。调用sleep不会释放对象锁。
  • wait是Object类的方法,对此对象调用wait方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify方法(或notifyAll)后本线程才进入对象锁定池准备获得对象锁进入运行状态。

Java基础(简答)- - - - - -多线程(简述synchronized和java.util.concurrent.locks.Lock的异同 ?)

  • 主要相同点:Lock能完成synchronized所实现的所有功能
  • 主要不同点:Lock有比synchronized更精确的线程语义和更好的性能。synchronized会自动释放锁,而Lock一定要求程序员手工释放,并且必须在finally从句中释放

Java基础(习题)- - - - - -多线程(模拟银行取钱的问题)

在这里插入图片描述
Account类

public class Account {
    
    
	private String idString;
	private double balance;

	public Account() {
    
    
		super();
	}
	public Account(String idString, double balance) {
    
    
		super();
		this.idString = idString;
		this.balance = balance;
	}
	public String getIdString() {
    
    
		return idString;
	}
	public void setIdString(String idString) {
    
    
		this.idString = idString;
	}
	public double getBalance() {
    
    
		return balance;
	}
	public void setBalance(double balance) {
    
    
		this.balance = balance;
	}
	@Override
	public int hashCode() {
    
    
		final int prime = 31;
		int result = 1;
		result = prime * result + ((idString == null) ? 0 : idString.hashCode());
		return result;
	}
	@Override
	public boolean equals(Object obj) {
    
    
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Account other = (Account) obj;
		if (idString == null) {
    
    
			if (other.idString != null)
				return false;
		} else if (!idString.equals(other.idString))
			return false;
		return true;
	}
	@Override
	public String toString() {
    
    
		return "Account [idString=" + idString + ", balance=" + balance + "]";
	}
	
	

}

测试类
在这里插入图片描述

Java(Dug)- - - - - -eclipse鼠标变成十字架解决方法

  • 使用快捷键:alt+shift+a

Java基础(习题)- - - - - -多线程(龟兔赛跑的问题)

/*
 * 编写龟兔赛跑多线程程序,设赛跑长度为100米,每跑完10米输出一次结果。
改进上题的龟兔赛跑程序,通过改变优先级,
并减掉休眠时间,使得乌龟以迅雷不及掩耳的速度跑完100米。
 */


public class Demo5 {
    
    
	public static void main(String[] args) {
    
    
		TortoiseRun tesTortoiseRun = new TortoiseRun();
		RabbitRun testRabbitRun  = new RabbitRun();
		
		Thread t1 = new Thread(tesTortoiseRun);
		Thread t2 = new Thread(testRabbitRun);
		t1.setName("乌龟");
		t2.setName("兔子");
		t1.start();
		t2.start();
		
	}

}
//乌龟跑100米
class TortoiseRun implements Runnable{
    
    
	int journey = 100;
	
	@Override
	public void run() {
    
    
		synchronized (this) {
    
    
			for(int i = 0;i <= 100;i++) {
    
    
				try {
    
    
					Thread.sleep(20);
				}catch(InterruptedException e) {
    
    
					e.printStackTrace();
				}
				if(i==10 || i==20||i==30 || i==40||i==50 || i==60||i==70 || i==80||i==90 || i==100) {
    
    
					System.out.println(Thread.currentThread().getName() +"跑了" + i + "米");
				}
			}	
		}
	}
}
class RabbitRun implements Runnable{
    
    
	
	int journey = 100;
	@Override
	public void run() {
    
    
		synchronized (this) {
    
    
			for(int i = 0;i <= 100;i++) {
    
    
				try {
    
    
					Thread.sleep(50);
				}catch(InterruptedException e) {
    
    
					e.printStackTrace();
				}
				if(i==10 || i==20||i==30 || i==40||i==50 || i==60||i==70 || i==80||i==90 || i==100) {
    
    
					System.out.println(Thread.currentThread().getName() +"跑了" + i + "米");
				}
			}
		}
	}	
}


测试结果
在这里插入图片描述

Java基础(习题)- - - - - -多线程(同步监视器的选取)

/*
 * 启动两个线程对一个数字i操作
 *1)其中1个线程每次对i加1
 *2)另1个线程每次对i减1
 *各运行20次,结果i的值等于初始值。
 */
public class Demo6 {
    
    
	public static void main(String[] args) {
    
    
		number num = new number(20);
		Add add = new Add(num);
		Sub sub = new Sub(num);
		Thread t1 = new Thread(add);
		Thread t2 = new Thread(sub);
		t1.setName("+1操作:");
		t2.setName("-1操作:");
		t1.start();
		t2.start();
//		try {
    
    
//			t1.join(15);
//		}catch (InterruptedException e) {
    
    
//			e.printStackTrace();
//		}
//		try {
    
    
//			t2.join(14);
//		} catch (InterruptedException e) {
    
    
//			e.printStackTrace();
//		}
	}

}
class number{
    
    
	private static int i;
	public number(int i) {
    
    
		this.i = i;
	}
	public int getI() {
    
    
		return i;
	}
	public void setI() {
    
    
		this.i =i;
	}
	public void sub() {
    
    
		i--;
	}
	public void add() {
    
    
		i++;
	}
}

class Add implements Runnable{
    
    
	private number num;
	public Add(number num) {
    
    
		this.num = num;
	}
	public void run() {
    
    
		synchronized (num) {
    
    
			for(int j = 0; j < 20; j++){
    
    
				
				try {
    
    
					Thread.sleep(20);
				}catch(InterruptedException e) {
    
    
					e.printStackTrace();
				}
				num.add();
				System.out.println(Thread.currentThread().getName() + "对i+1后,i 的值为:" + num.getI());
			}
		}
	}
	
}
class Sub implements Runnable{
    
    
	private number num;
	public Sub(number num) {
    
    
		this.num = num;
	}
	@Override
	public void run() {
    
    
		synchronized (num) {
    
    
			for(int j = 0; j < 20; j++){
    
    
				try {
    
    
					Thread.sleep(20);
				}catch(InterruptedException e) {
    
    
					e.printStackTrace();
				}
				num.sub();
				System.out.println(Thread.currentThread().getName() + "对i-1后,i 的值为:" + num.getI());
			}
		}
	}
}

这里应该将数字i作为一个属性封装在另一个Number类中,并使用Number类的对象作为同步监视器,这样可以使得多个线程共用一个同步监视器。

Java基础(习题)- - - - - -多线程(notify()、wait()方法能够确保线程不能够连续打印)

/*
 * 实现一个由A、B、C三个窗口同时销售100张票的系统,
 * 要求打印出每个窗口打印的售票情况,并且每个窗口不得连续售票
 */

public class Demo7 {
    
    
	public static void main(String[] args) {
    
    
		windows testWindows = new windows();
		Thread t1 = new Thread(testWindows);
		Thread t2 = new Thread(testWindows);
		Thread t3 = new Thread(testWindows);
		t1.setName("窗口一");
		t2.setName("窗口二");
		t3.setName("窗口三");
		t1.start();
		t2.start();
		t3.start();
	}
	

}
class windows implements Runnable{
    
    
	private static int titck = 1;
	
	@Override
	public void run() {
    
    
		while(titck < 99) {
    
    
			synchronized (this) {
    
    
				this.notify();
				
				try {
    
    
					Thread.sleep(10);
				}catch(InterruptedException e) {
    
    
					e.printStackTrace();
				}
				System.out.println(Thread.currentThread().getName() + "票号为:" + titck);
				titck++;
				try {
    
    
					this.wait();
				}catch (InterruptedException e) {
    
    
					e.printStackTrace();
				}
			
			}
		}
						
	}
}

猜你喜欢

转载自blog.csdn.net/m0_51755061/article/details/113859574
今日推荐