7

JUC(1)线程和进程、并发和并行、线程的状态、lock锁、生产者和消费者问题

 2 years ago
source link: https://blog.51cto.com/u_15740728/5542265
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

JUC(1)线程和进程、并发和并行、线程的状态、lock锁、生产者和消费者问题

推荐 原创

郑同学要努力呀 2022-08-04 08:53:49 ©著作权

文章标签 java i++ javascript 文章分类 Linux 系统/运维 阅读数217

JUC(1)线程和进程、并发和并行、线程的状态、lock锁、生产者和消费者问题_javascript

1、线程和进程

  • 进程:一个程序,微信、qq、、、程序的集合。(一个进程包含多个线程,至少包含一个线程。java默认有两个线程:主线程(main)、垃圾回收线程(GC)
  • 线程:runnable、thread 、callable
    java开不了线程,在源码中可以看出,调用的是底层的方法
private native void start0();
JUC(1)线程和进程、并发和并行、线程的状态、lock锁、生产者和消费者问题_javascript_02

2、并发和并行

  • 并发:交替
  • 并行:同时(同一个时间)
    并发编程的本质:充分利用cpu的资源

3、线程的状态

public enum State {
/**
* Thread state for a thread which has not yet started.
*/
NEW,

/**
* Thread state for a runnable thread. A thread in the runnable
* state is executing in the Java virtual machine but it may
* be waiting for other resources from the operating system
* such as processor.
*/
RUNNABLE,

/**
* Thread state for a thread blocked waiting for a monitor lock.
* A thread in the blocked state is waiting for a monitor lock
* to enter a synchronized block/method or
* reenter a synchronized block/method after calling
* {@link Object#wait() Object.wait}.
*/
BLOCKED,

/**
* Thread state for a waiting thread.
* A thread is in the waiting state due to calling one of the
* following methods:
* <ul>
* <li>{@link Object#wait() Object.wait} with no timeout</li>
* <li>{@link #join() Thread.join} with no timeout</li>
* <li>{@link LockSupport#park() LockSupport.park}</li>
* </ul>
*
* <p>A thread in the waiting state is waiting for another thread to
* perform a particular action.
*
* For example, a thread that has called <tt>Object.wait()</tt>
* on an object is waiting for another thread to call
* <tt>Object.notify()</tt> or <tt>Object.notifyAll()</tt> on
* that object. A thread that has called <tt>Thread.join()</tt>
* is waiting for a specified thread to terminate.
*/
WAITING,

/**
* Thread state for a waiting thread with a specified waiting time.
* A thread is in the timed waiting state due to calling one of
* the following methods with a specified positive waiting time:
* <ul>
* <li>{@link #sleep Thread.sleep}</li>
* <li>{@link Object#wait(long) Object.wait} with timeout</li>
* <li>{@link #join(long) Thread.join} with timeout</li>
* <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li>
* <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li>
* </ul>
*/
TIMED_WAITING,

/**
* Thread state for a terminated thread.
* The thread has completed execution.
*/
TERMINATED;
}
  • 等待,(死死的等)

4、sleep和wait的区别

  • sleep来自thread。wait来自object
  • wait会释放锁,sleep不会释放锁
  • wait只能在同步代码块中,sleep可以在任意地方睡

5、Lock锁

Lock接口

JUC(1)线程和进程、并发和并行、线程的状态、lock锁、生产者和消费者问题_i++_03

public interface Lock
Lock实现提供比使用synchronized方法和语句可以获得的更广泛的锁定操作。 它们允许更灵活的结构化,可能具有完全不同的属性,并且可以支持多个相关联的对象Condition 。
锁是用于通过多个线程控制对共享资源的访问的工具。 通常,锁提供对共享资源的独占访问:一次只能有一个线程可以获取锁,并且对共享资源的所有访问都要求首先获取锁。 但是,一些锁可能允许并发访问共享资源,如ReadWriteLock的读锁。

使用synchronized方法或语句提供对与每个对象相关联的隐式监视器锁的访问,但是强制所有锁获取和释放以块结构的方式发生:当获取多个锁时,它们必须以相反的顺序被释放,并且所有的锁都必须被释放在与它们相同的词汇范围内。

虽然synchronized方法和语句的范围机制使得使用监视器锁更容易编程,并且有助于避免涉及锁的许多常见编程错误,但是有时您需要以更灵活的方式处理锁。 例如,用于遍历并发访问的数据结构的一些算法需要使用“手动”或“链锁定”:您获取节点A的锁定,然后获取节点B,然后释放A并获取C,然后释放B并获得D等。 所述的实施方式中Lock接口通过允许获得并在不同的范围释放的锁,并允许获得并以任何顺序释放多个锁使得能够使用这样的技术。

JUC(1)线程和进程、并发和并行、线程的状态、lock锁、生产者和消费者问题_i++_04

synchronized和lock的区别

  • 1、synchronized内置的java关键字,lock是一个java类
  • 2、synchronized 无法判断获取锁的状态,lock锁可以判断是否获取到了锁
  • 3、synchronized会自动释放锁,lock必须要手动释放锁,如果不释放锁,死锁
  • 4、synchronized 线程1获得锁,阻塞,线程2 傻傻的等。lock锁就不一定会等下去;会试图获取锁
  • 5、synchronized 可重入锁,不可以中断,非公平:lock,可重入锁可以判断锁,非公平
  • 6、synchronized 适合锁少量的代码同步问题,lock适合锁大量的同步代码
JUC(1)线程和进程、并发和并行、线程的状态、lock锁、生产者和消费者问题_javascript_05

6、买票问题

7、生产者和消费者问题

JUC(1)线程和进程、并发和并行、线程的状态、lock锁、生产者和消费者问题_javascript_06
JUC(1)线程和进程、并发和并行、线程的状态、lock锁、生产者和消费者问题_i++_07
JUC(1)线程和进程、并发和并行、线程的状态、lock锁、生产者和消费者问题_i++_08

8、使用condition替换synchronized

JUC(1)线程和进程、并发和并行、线程的状态、lock锁、生产者和消费者问题_i++_09
JUC(1)线程和进程、并发和并行、线程的状态、lock锁、生产者和消费者问题_javascript_10

修改后的代码

package com.pc;

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

/**
* 线程之间的通信,生产者和消费者问题
*/
public class PC {
public static void main(String[] args) {
Data data = new Data();
new Thread(()->{
for (int i = 0; i < 5; i++) {
try {
data.increment();
} catch (InterruptedException e) {
e.printStackTrace();
}
}

},"A").start();

new Thread(()->{
for (int i = 0; i < 5; i++) {
try {
data.decrement();
} catch (InterruptedException e) {
e.printStackTrace();
}
}

},"B").start();

new Thread(()->{
for (int i = 0; i < 5; i++) {
try {
data.increment();
} catch (InterruptedException e) {
e.printStackTrace();
}
}

},"C").start();

new Thread(()->{
for (int i = 0; i < 5; i++) {
try {
data.decrement();
} catch (InterruptedException e) {
e.printStackTrace();
}
}

},"D").start();

}
}


//等待,业务,通知
class Data {
//资源类
private int num = 0;
Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();

/**
* condition.await();//等待
* condition.signalAll();//通知
*/

//增加操作
public void increment() throws InterruptedException {
try {
lock.lock();
while (num != 0) {
//等待
condition.await();
}
num++;
System.out.println(Thread.currentThread().getName() + "=>" + num);
//通知
condition.signalAll();
} finally {
lock.unlock();
}


}

//减少操作
public void decrement() throws InterruptedException {
try {
//第一步上锁
lock.lock();
while (num == 0) {
//等待
condition.await();
}
num--;
System.out.println(Thread.currentThread().getName() + "=>" + num);
//通知
condition.signalAll();
} finally {
lock.unlock();

}

}
}
JUC(1)线程和进程、并发和并行、线程的状态、lock锁、生产者和消费者问题_i++_11
  • 收藏
  • 评论
  • 分享
  • 举报

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK