面试总结之并发编程

299 阅读2分钟
1、现在有T1、T2、T3三个线程,你怎样保证T2在T1执行完后执行,T3在T2执行完后执行?
解法1

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class SequentialExecutionTest2 {
    private static Lock lock = new ReentrantLock();
    private static int state = 0;

    class ThreadA extends Thread {
        @Override
        public void run() {
            lock.lock();
            if (state % 3 == 0) {
                System.out.println("A");
                state++;
            }
            lock.unlock();
        }
    }

    class ThreadB extends Thread {
        @Override
        public void run() {
            lock.lock();
            if (state % 3 == 1) {
                System.out.println("B");
                state++;
            }
            lock.unlock();
        }

    }

    class ThreadC extends Thread {
        @Override
        public void run() {
            lock.lock();
            if (state % 3 == 2) {
                System.out.println("C");
                state++;
            }
            lock.unlock();
        }
    }

    public static void main(String[] args) {
        SequentialExecutionTest2 test2 = new SequentialExecutionTest2();
        new Thread(test2.new ThreadA()).start();
        new Thread(test2.new ThreadB()).start();
        new Thread(test2.new ThreadC()).start();
    }

}
解法2
public class SequentialExecutionTest1 {

    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(new Runner("A"));
        Thread t2 = new Thread(new Runner("B"));
        Thread t3 = new Thread(new Runner("C"));
        t1.start();
        t1.join();
        t2.start();
        t2.join();
        t3.start();
        t3.join();
    }
}

class Runner implements Runnable {
    public String name;

    Runner(String name) {
        this.name = name;
    }

    @Override
    public void run() {
        System.out.println(name + "");

    }
}
2、在java中wait和sleep方法的不同?
3、什么是原子操作,Java 中的原子操作是什么?

原子操作:是指不会被线程调度机制打断的操作。这种操作一旦开始,就一直运行到结束,中间不会有任何 context switch。

  i++;

上述代码不是原子操作;涉及三个步骤

  • 1、读取i的值;
  • 2、+1操作;
  • 3、赋值操作

参考: Java中atomic包中的原子操作类总结

用Java编程一个会导致死锁的程序,你将怎么解决?
import java.util.Date;

public class DeadLockTest1 {
    public static String obj1 = "obj1";
    public static String obj2 = "obj2";
    public static void main(String[] args) {
        LockA la = new LockA();
        new Thread(la).start();
        LockB lb = new LockB();
        new Thread(lb).start();
    }
}
class LockA implements Runnable{
    public void run() {
        try {
            System.out.println(new Date().toString() + " LockA 开始执行");
            while(true){
                synchronized (DeadLockTest1.obj1) {
                    System.out.println(new Date().toString() + " LockA 锁住 obj1");
                    Thread.sleep(3000); // 此处等待是给B能锁住机会
                    synchronized (DeadLockTest1.obj2) {
                        System.out.println(new Date().toString() + " LockA 锁住 obj2");
                        Thread.sleep(60 * 1000); // 为测试,占用了就不放
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
class LockB implements Runnable{
    public void run() {
        try {
            System.out.println(new Date().toString() + " LockB 开始执行");
            while(true){
                synchronized (DeadLockTest1.obj2) {
                    System.out.println(new Date().toString() + " LockB 锁住 obj2");
                    Thread.sleep(3000); // 此处等待是给A能锁住机会
                    synchronized (DeadLockTest1.obj1) {
                        System.out.println(new Date().toString() + " LockB 锁住 obj1");
                        Thread.sleep(60 * 1000); // 为测试,占用了就不放
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}