关于线程的常见问题-
-
什么是并发与并行?
- 并行:两个或者多个事件在同一时刻发生
- 并发:两个或者多个事件在同一个时间段内发生
-
什么是进程与线程?
- 进程是正在运行的程序的实例
- 进程是线程的容器,一个进程可以开启多个线程
- 比如打开一个浏览器,会创建进程
-
线程如何创建?
- 继承Thread类
- 实现Runnable接口
- 实现Callable接口鸭
- 从线程池-Excutor 获取线程
- 实现类接口和继承类接口的比较:
- 接口更适合多个相同的程序代码去共享同一个资源
- 接口可以避免java中单继承的局限性
- 接口代码可以被多个线程共享,代码和线程独立
- 线程池只能 放入实现Runnable和Callable接口的线程,不能直接放入继承Thread的线程
- java中,每次运行程序至少启动2个线程,一个是main线程,一个是垃圾收集线程
- 线程的生命周期?
- 什么是线程安全问题?线程安全问题解决方案?
-
- 线程安全问题都是由全局变量及静态变量引起的
- 若每个线程对全局变量,静态变量只读,不写,则这个变量是线程安全的
- 若有多个线程同时执行写操作,则需要考虑线程同步,否则就可能影响线程安全
-
- 解决方案 :线程同步 - 只要在某个线程修改共享资源的时候,其他线程不能修改该资源,等待修改完毕同步之后,才能去抢夺资源,完成对应的操作,保证了数据的同步性。
- java引入了7种同步机制:
- 同步代码块(synchronized)
- 同步方法(synchronized)
- 同步锁(ReentrantLock)
- 特殊域变量(volatile)
- 局部变量(ThreadLocal)
- 阻塞队列(LinkedBlockingQueue)
- 原子变量(Atomic*)
- 什么是线程死锁?死锁的必要条件?如何避免死锁?
- 线程如何通讯?
- 多线程并发执行时,在默认情况下cpu是随机切换的,有时我们希望cpu按我们的规律执行线程,此时就需要线程之间的协调通信
-
- notify() & wait() 方法切换线程示例打印奇数偶数:
-
1 public class ThreadTCPDemo { 2 private int i = 0; 3 private Object obj = new Object(); 4 5 public void odd() { 6 // 判断是否小于10 7 while (i < 10) { 8 synchronized (obj) { 9 // 打印奇数 10 if (i % 2 == 1) { 11 System.out.println("奇数:" + i); 12 i++; 13 obj.notify(); // 唤醒偶数线程打印 14 } else { 15 try { 16 obj.wait(); // 等待偶数线程打印完毕 17 } catch (Exception e) { 18 e.printStackTrace(); 19 } 20 } 21 } 22 } 23 } 24 public void even() { 25 // 判断是否小于10 26 while (i < 10) { 27 synchronized (obj) { 28 // 打印奇数 29 if (i % 2 == 0) { 30 System.out.println("偶数:" + i); 31 i++; 32 obj.notify(); // 唤醒奇数线程打印 33 } else { 34 try { 35 obj.wait(); // 等待奇数线程打印完毕 36 } catch (Exception e) { 37 e.printStackTrace(); 38 } 39 } 40 } 41 } 42 } 43 public static void main(String[] args) { 44 final ThreadTCPDemo threadTCPDemo = new ThreadTCPDemo(); 45 46 Thread thread = new Thread(new Runnable() { 47 @Override 48 public void run() { 49 threadTCPDemo.odd(); 50 } 51 }); 52 Thread thread2 = new Thread(new Runnable() { 53 @Override 54 public void run() { 55 threadTCPDemo.even(); 56 } 57 }); 58 thread.start(); 59 thread2.start(); 60 } 61 }
-
- Condition 的signal()&await()方法切换线程示例打印奇数偶数:
-
1 public class ThreadTCPDemo { 2 private int i = 0; 3 // private Object obj = new Object(); 4 private Lock lock = new ReentrantLock(false); 5 private Condition condition = lock.newCondition(); 6 7 public void odd() { 8 // 判断是否小于10 9 while (i < 10) { 10 lock.lock(); // 加锁 11 try { 12 // 打印奇数 13 if (i % 2 == 1) { 14 System.out.println("奇数:" + i); 15 i++; 16 condition.signal(); // 唤醒偶数线程打印 17 } else { 18 try { 19 condition.await(); // 等待偶数线程打印完毕 20 } catch (Exception e) { 21 e.printStackTrace(); 22 } 23 } 24 } catch (Exception e) { 25 e.printStackTrace(); 26 } finally { 27 lock.unlock(); 28 } 29 } 30 } 31 32 public void even() { 33 // 判断是否小于10 34 while (i < 10) { 35 lock.lock(); 36 try { 37 // 打印偶数 38 if (i % 2 == 0) { 39 System.out.println("偶数:" + i); 40 i++; 41 condition.signal(); // 唤醒奇数线程打印 42 } else { 43 try { 44 condition.await(); // 等待奇数线程打印完毕 45 } catch (Exception e) { 46 e.printStackTrace(); 47 } 48 } 49 } catch (Exception e) { 50 e.printStackTrace(); 51 } finally { 52 lock.unlock(); 53 } 54 } 55 } 56 57 public static void main(String[] args) { 58 final ThreadTCPDemo threadTCPDemo = new ThreadTCPDemo(); 59 60 Thread thread = new Thread(new Runnable() { 61 @Override 62 public void run() { 63 threadTCPDemo.odd(); 64 } 65 }); 66 Thread thread2 = new Thread(new Runnable() { 67 @Override 68 public void run() { 69 threadTCPDemo.even(); 70 } 71 }); 72 thread.start(); 73 thread2.start(); 74 } 75 }
-
- notify() & wait() 方法切换线程示例打印奇数偶数:
来源:https://www.cnblogs.com/padazala/p/12650387.html