Java多线程编程全解析
System.out.println("处理数据,还能处理"+Desk.count+"条");:多个线程形成环形等待链(如线程 1 等待线程 2 的资源,线程 2 等待线程 1 的资源)。当非守护线程执行完后,守护线程也会陆续结束(不一定全部执行完):资源只能被一个线程占用(如一把锁只能被一个线程持有)。:线程持有至少一个资源,同时等待获取其他线程持有的资源。join()插入的线程全部执行完才会执
一、线程和进程
进程是程序执行的一次过程
线程是进程内的一个执行单元
一个进程可能包含多个线程(至少有一个主线程)
二、并行和并发
并发是单个CPU上交替执行多个任务
并行是多个CPU上可同时执行多个任务
三、多线程的实现方式
1、继承Thread类
@Test
public void method() {
MyThread myThread1=new MyThread();
MyThread myThread2=new MyThread();
myThread1.start();
myThread2.start();
}
class MyThread extends Thread{
public void run(){
for (int i = 0; i < 5; i++) {
System.out.println(i);
}
}
}
2、实现Runnable接口,重写run()
@Test
public void method() {
MyThread myThread1=new MyThread();
Thread thread1=new Thread(myThread1);
Thread thread2=new Thread(myThread1);
thread1.start();
thread2.start();
}
class MyThread implements Runnable{
public void run(){
for (int i = 0; i < 5; i++) {
System.out.println(i);
}
}
}
3、实现Callable接口
@Test
public void method() throws ExecutionException, InterruptedException {
MyThread myThread=new MyThread();
FutureTask<Integer> futureTask=new FutureTask<>(myThread);
Thread thread1=new Thread(futureTask);
thread1.start();
Integer integer = futureTask.get();
System.out.println(integer);
}
class MyThread implements Callable<Integer> {
@Override
public Integer call() throws Exception {
int sum=0;
for (int i = 0; i < 10; i++) {
sum+=i;
}
return sum;
}
}
四、线程优先级
抢占式调度 随机
设置优先级setPriority() 只是增大抢占的概率 并不是一定先执行
非抢占式调度 顺序执行
五、守护线程
setDaemon(boolean)
当非守护线程执行完后,守护线程也会陆续结束(不一定全部执行完)
六、礼让线程
yield()让出当前CPU的执行权
但每次线程执行会重新抢夺CPU(用处不大)
七、插入线程
join()插入的线程全部执行完才会执行下一个线程
八、线程的生命周期
新建(New)→ 就绪(Runnable)→ 运行(Running)→ 终止(Terminated)
↑ ↓
└─ 阻塞/等待/超时等待 ←─┘
九、同步代码块
public class demo {
public static void main(String[] args) {
MyThread myThread = new MyThread();
Thread thread1 = new Thread(myThread);
Thread thread2 = new Thread(myThread);
Thread thread3 = new Thread(myThread);
thread1.start();
thread2.start();
thread3.start();
}
}
class MyThread implements Runnable {
static int i=1;
@Override
public void run() {
while (i<500){
//锁对象只能是唯一的 不能写在循环的外面
synchronized (MyThread.class) {
System.out.println(Thread.currentThread().getName() + i );
i++;
try {
sleep(100);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
十、同步方法
public synchronized xxx(){
//实现方法
}
十一、锁
public class demo {
public static void main(String[] args) {
MyThread myThread = new MyThread();
Thread thread1 = new Thread(myThread);
Thread thread2 = new Thread(myThread);
Thread thread3 = new Thread(myThread);
thread1.start();
thread2.start();
thread3.start();
}
}
class MyThread implements Runnable {
int t=1;
Lock lock=new ReentrantLock();
@Override
public void run() {
while(true){
lock.lock();
try {
if (t == 200) {
break;
} else {
System.out.println(Thread.currentThread().getName() + "-----------" + t);
t++;
sleep(100);
}
}catch (InterruptedException e) {
throw new RuntimeException(e);
}finally {
lock.unlock();
}
}
}
}
十二、死锁
死锁:指两个或多个线程相互等待对方释放资源而陷入无限阻塞的状态。
产生死锁的条件:
-
互斥条件:资源只能被一个线程占用(如一把锁只能被一个线程持有)。
-
持有并等待:线程持有至少一个资源,同时等待获取其他线程持有的资源。
-
不可剥夺:线程已获得的资源不能被强制剥夺,只能主动释放。
-
循环等待:多个线程形成环形等待链(如线程 1 等待线程 2 的资源,线程 2 等待线程 1 的资源)。
解决死锁的方法:
1、让所有线程按顺序获取资源,避免循环等待
2、使用tryLock()获取限时锁,超时自动释放
3、减少锁的持有时间,缩短加锁的代码块范围,减少线程等待时间
4、使用ThreadMaxBean,定时检测死锁,检测出死锁即终止线程
十三、等待唤醒机制(生产者和消费者)
消费者:
1、判断是否有数据
2、没有则等待
3、有则处理数据
4、处理后唤醒生产者
生产者:
1、判断是否有数据
2、有则等待
3、没有则产生数据
4、将数据传给消费者
5、唤醒消费者
wait()当前线程等待,直到被其他线程唤醒
notify() 随机唤醒单个线程
notifyAll() 唤醒所有线程
public class demo {
public static void main(String[] args) {
Consumer consumer=new Consumer();
Productor productor=new Productor();
Thread thread1=new Thread(consumer);
Thread thread2=new Thread(productor);
thread1.setName("消费者");
thread2.setName("生产者");
thread1.start();
thread2.start();
}
}
class Consumer implements Runnable{
@Override
public void run() {
while(true){
synchronized (Desk.lock){
if(Desk.count==0)
break;
else {
if(Desk.food!=0){
Desk.count--;
System.out.println("处理数据,还能处理"+Desk.count+"条");
Desk.lock.notifyAll();
Desk.food=0;
}
else {
try {
Desk.lock.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
}
}
}
class Desk{
static int food=0;
static int count=10;
static Object lock=new Object();
}
class Productor implements Runnable{
@Override
public void run() {
while (true){
synchronized (Desk.lock){
if(Desk.count==0)
break;
else{
if(Desk.food==1){
try {
Desk.lock.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
else {
System.out.println("产生一条数据");
Desk.food=1;
Desk.lock.notifyAll();
}
}
}
}
}
}
更多推荐


所有评论(0)