测试环境:
系统:Windex
JDK:1.8
工具:Eclipse
进程和线程的区别是什么?
答:进程就是线程的集合,而每个线程就是一条执行路径且互不影响。
创建线程的3种方法:
第一种: 继承 Thread 类
public class ThreadDome extends Thread {
public static void main(String[] args) {
TestThread threadDome = new TestThread();
threadDome.start();
new TestThread().start();
}
}
class TestThread extends Thread {
@Override
public void run() {
for(int i=0;i<30;i++) {
System.out.println("第:"+i);
}
}
}
第二种 实现 Runnable 接口:
public class RunnableDome {
public static void main(String[] args) {
MyTest myTest = new MyTest();
Thread thread = new Thread(myTest);
thread.start();
Thread thread2 = new Thread(myTest);
thread2.start();
}
}
class MyTest implements Runnable{
@Override
public void run() {
for(int i=0;i<100;i++) {
System.out.println("第:"+i);
}
}
}
第三种 匿名内部类方式:
public static void main(String[] args) {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
for(int i=0;i<100;i++){
System.out.println(i);
}
}
});
thread.start();
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
for(int i=0;i<100;i++){
System.out.println(i);
}
}
});
thread2.start();
}
//这种方法在 WEB 开发中 不是经常用到 但是在 桌面程序用的比较多
JAVA 线程中常用的 API方法:
- start() 启动线程
- currentThread() 获取当前线程对象
- getID() 获取当前线程ID Thread-编号 该编号从0开始
- getName() 获取当前线程名称
- sleep(long mill) 休眠线程
- Stop() 停止线程
- 常用线程构造函数
- Thread() 分配一个新的 Thread 对象
- Thread(String name) 分配一个新的 Thread对象,具有指定的 name正如其名。
- Thread(Runable r) 分配一个新的 Thread对象
- Thread(Runable r, String name) 分配一个新的 Thread对象
JAVA 线程的 5 种状态
1.新建状态:
你创建的 线程 没有调用 start() 方法的时候称之为 新建状态
12. 就绪状态
掉用 start() 方法 后加入到 CPU 任务列表 进行随机 选取
3.运行状态
线程获取 到 CPU 资源后的状态 正在执行 run 方法
4.阻塞状态
1>线程通过调用sleep方法进入睡眠状态;
2>线程调用一个在I/O上被阻塞的操作,即该操作在输入输出操作完成之前不会返回到它的调用者;
3>线程试图得到一个锁,而该锁正被其他线程持有;
4>线程在等待某个触发条件;
5.阻塞状态 后还会 进入 就绪状态----运行状态------阻塞状态 进行 循环直到run 方法执行完毕 或 捕获的异常终止进入死亡状态
6.死亡状态
1) run方法正常退出而自然死亡,
2) 一个未捕获的异常终止了run方法而使线程猝死。
线程安全:
什么是多线程安全?
答:线程安全是多个线程在操作同一个全局变量或静态变量 进行写操作时可能出现的数据错误
如何解决多线程之间线程安全问题?
答:加入同步 或者 lock 锁
synchronized 和 lock 的区别 :
synchronized 会自动释放锁 默认 是 this
lock 要手动 释放锁
为什么使用线程同步或使用锁能解决线程安全问题呢?
答: 保证 代码块只能有一个线程执行 当写入 一个全局变量或静态变量 保证 线程2 不会 在进行 写入
什么是多线程之间同步?
答:当多个线程同步同一个资源,不受其他线程干扰
什么是同步代码块?
答:就是将 可能发生线程数据不安全的地方使用synchronized 进行包裹
问:同步函数与静态同步函数区别?
同步函数使用this锁
静态同步函数使用字节码文件,也就是类.class
问:什么是多线程死锁?
答:同步中嵌套同步
解决办法:同步中尽量不要嵌套同步
多线程之间实现通讯
设 工程 A 生产一个 商品 销售员 B将 商品 卖出 :
线程 A 进行生产
线程B 进行卖出
当 2个线程同时 运行时会造成 数据错误 可以使用 同步代码块 在 写入 和 读取 时加入
wait() 方法:
当前线程变为等待,但是可以释放锁
notify方法
如果对象调用了notify方法就会通知某个正在等待这个对象的控制权的线程可以继续运行。
notifyAll方法
notifyAll方法就会通知所有等待这个对象控制权的线程继续运行。
wait与sleep区别?
在调用sleep()方法的过程中,线程不会释放对象锁。
而当调用wait()方法的时候,线程会放弃对象锁
Lock 接口与 synchronized 关键字的区别
Lock 接口可以尝试非阻塞地获取锁 当前线程尝试获取锁。如果这一时刻锁没有被其他线程获取到,则成功获取并持有锁。
*Lock 接口能被中断地获取锁 与 synchronized 不同,获取到锁的线程能够响应中断,当获取到的锁的线程被中断时,中断异常将会被抛出,同时锁会被释放。
Lock 接口在指定的截止时间之前获取锁,如果截止时间到了依旧无法获取锁,则返回。
3.3 Condition用法
Condition的功能类似于在传统的线程技术中的,Object.wait()和Object.notify()的功能,
Condition condition = lock.newCondition();
res. condition.await(); 类似wait
res. Condition. Signal() 类似notify
守护线程
setDaemon(true)方法设置为守护线程
深入理解Java多线程与并发编程
多线程三大特性
1.原子性
2.可见性
3.有序性
Volatile 关键字 :
设置 变量 其他 线程可见,不能保证线程安全
ThreadLoca 本地线程:
public static ThreadLocal<Integer> threadLocal = new ThreadLocal<Integer>() {
protected Integer initialValue() {
return 0;
};
创建 一个本地 的线程 变量
线程池四种创建方式
newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。
newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
cachedThreadPool.execute(new Runnable() {
public void run() {
System.out.println(Thread.currentThread().getName() + "---" + index);
}
});
}