2021.2.19
- Java基础(简答)- - - - - -多线程(修饰同步方法? stop()和suspend()方法为何不推荐使用?)
- Java基础(简答)- - - - - -多线程(sleep() 和 wait() 有什么区别? )
- Java基础(简答)- - - - - -多线程(简述synchronized和java.util.concurrent.locks.Lock的异同 ?)
- Java基础(习题)- - - - - -多线程(模拟银行取钱的问题)
- Java(Dug)- - - - - -eclipse鼠标变成十字架解决方法
- Java基础(习题)- - - - - -多线程(龟兔赛跑的问题)
- Java基础(习题)- - - - - -多线程(同步监视器的选取)
- Java基础(习题)- - - - - -多线程(notify()、wait()方法能够确保线程不能够连续打印)
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();
}
}
}
}
}