java多线程面试题
1、有三个线程ID分别是A、B、C,请有多线编程实现,在屏幕上循环打印10次ABCABC…
由于线程执行的不确定性,要保证这样有序的输出,必须控制好多线程的同步。
线程同步有两种基本方法:
(1) synchronized
(2) wait,notify,notifyAll
现在分别采用这两种方法来解答这道题目。
注:此面试题主要考查,面试者线程并发的问题。可以参考:生产者-消费者模型。
方法1:使用 synhronized同步代码块
1 class Method1 implements Runnable { 2 private String name = ""; 3 private StartLock lock = null; 4 private int count = 10; 5 6 public Method1(String name, StartLock lock) { 7 this.name = name; 8 this.lock = lock; 9 10 } 11 12 public void run() { 13 while (count > 0) { 14 synchronized (lock) { 15 if (lock.getName().equalsIgnoreCase(this.name)) { 16 System.out.print("当前线程名:" 17 + Thread.currentThread().getName() + " " + name 18 + " "); 19 20 if (name == "C") { 21 System.out.println(); 22 } 23 24 count--; 25 26 if (this.name.equals("A")) { 27 lock.setName("B"); 28 } else if (this.name.equals("B")) { 29 lock.setName("C"); 30 } else if (this.name.equals("C")) { 31 lock.setName("A"); 32 } 33 } 34 } 35 } 36 } 37 }
方法2:使用 wait,notify,notifyAll
1 class Method2 implements Runnable { 2 private String name = ""; 3 private StartLock lock = null; 4 private int count = 10; 5 6 public Method2(String name, StartLock lock) { 7 this.name = name; 8 this.lock = lock; 9 } 10 11 public void run() { 12 while (count > 0) { 13 synchronized (lock) { 14 while (!lock.getName().equalsIgnoreCase(this.name)) { 15 try { 16 lock.wait(); 17 } catch (InterruptedException e) { 18 e.printStackTrace(); 19 } 20 } 21 22 System.out.print(name); 23 24 count--; 25 26 if (this.name.equals("A")) { 27 lock.setName("B"); 28 } else if (this.name.equals("B")) { 29 lock.setName("C"); 30 } else if (this.name.equals("C")) { 31 lock.setName("A"); 32 } 33 lock.notifyAll(); 34 } 35 } 36 } 37 }
测试:
1 class StartLock {//锁对象 2 public String name = "A"; 3 4 public String getName() { 5 return name; 6 } 7 public void setName(String name) { 8 this.name = name; 9 } 10 } 11 12 public class Test { 13 public static void main(String[] args) { 14 StartLock lock = new StartLock(); 15 16 //new Thread(new Method1("A", lock)).start(); 17 //new Thread(new Method1("B", lock)).start(); 18 //new Thread(new Method1("C", lock)).start(); 19 20 new Thread(new Method2("A", lock)).start(); 21 new Thread(new Method2("B", lock)).start(); 22 new Thread(new Method2("C", lock)).start(); 23 } 24 }