今天去了回客科技 笔试了一波。很遗憾啊,脑袋有思路 但是还没到手写代码很熟练的程度,基本功不到位。
第一道:线程的题:三个线程 +1 一个线程 -1 运算 。
看到网上还有四个线程的,两个加法计算,两个减法运算。基本的思路都是一样的 ,注意看同步处理。
下面贴出代码实现:
public class AddTest {
private static int i;
private static Object object = new Object();
public static void main(String[] args) {
new Thread(() -> {
synchronized (object) {
i++;
}
}).start();
new Thread(() -> {
synchronized (object) {
i++;
}
}).start();
new Thread(() -> {
synchronized (object) {
i++;
}
}).start();
new Thread(() -> {
synchronized (object) {
i--;
}
}).start();
//这里睡眠 等所有线程运行完毕 看最终的数值,2
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(i);
}
}
这里引申出来了其他问题的思考
第1种:
synchronized void add 修饰普通方法 等同于
synchronized (this)
public int i = 0;
public void add(String threadName) {
synchronized (this) {
i++;
System.out.println(threadName + "加法运算:" + i);
}
}
//上面代码等于如下代码:
public synchronized void add(String threadName) {
i++;
System.out.println(threadName + "加法运算:" + i);
}
第2种:
synchronized static void add 修饰静态方法 等同于
synchronized (*.class)
说明:以上两种我分析为 synchornized 修饰普通方法和this 对应的是同一个实例对象。而修饰静态方法和class 是对应的同一个类的 唯一的class对象。这个是我的理解,有错误之处请各位指正。在此谢过
第二道:一个线程加一运算,一个线程做减法运算,多个线程同时交替运行(延申的)
第1种方法:使用Synchronized 实现
public class Count {
private int num = 0;
private boolean flag = false; // 标识
//加法
public synchronized void add() {
while (flag) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.num++; //加
System.out.println(Thread.currentThread().getName() + "........" + this.num);
this.flag = true; //设置标识为true
notifyAll(); //唤醒所有在线程池中冻结的线程,会把所有都唤醒
}
//减法
public synchronized void sub() {
while (!flag) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.num--; //减
System.out.println(Thread.currentThread().getName() + "........" + this.num);
this.flag = false; //设置标识为true
notifyAll(); //唤醒所有在线程池中冻结的线程,会把所有都唤醒
}
}
第2种 :使用Lock 锁实现
public class CountLock {
private int num = 0;
private boolean flag = false; // 标识
Lock lock = new ReentrantLock(); // 锁
Condition add = lock.newCondition(); // 加法锁
Condition sub = lock.newCondition();// 减法锁
public void add() {
lock.lock();// 锁上
try {
while (flag) { //循环判断
add.await();
}
this.num++;
System.out.println(Thread.currentThread().getName() + "........" + this.num);
this.flag = true; // 设置标识
sub.signal(); // 唤醒指定线程
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void sub() {
lock.lock();// 锁上
try {
while (!flag) {//循环判断
sub.await();
}
this.num--;
System.out.println(Thread.currentThread().getName() + "........" + this.num);
this.flag = false; // 设置标识
add.signal(); // 唤醒指定线程
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
调用的 main 方法:
public static void main(String[] args) {
//Count c=new Count();
CountLock c=new CountLock();
Thread t1=new Thread(new Runnable() {
@Override
public void run() {
while (true) {
c.add();
}
}
});
Thread t2=new Thread(new Runnable() {
@Override
public void run() {
while (true){
c.sub();
}
}
});
t1.start();
t2.start();
//这里感觉线程少可以再启动 两个t3或者t4 来验证真实性
}
这里延申的知识点参考博客:
记录一次回客科技有关线程的笔试题,三个线程加法和一个线程减法 ,延申的两个线程交替执行
原文:https://www.cnblogs.com/liran123/p/9393153.html