进程:就是一个正在运行的程序
线程:就是进程内的多条执行路径,一个进程内有多个线程。
并行:多核cpu下,每个核心都可以运行线程。同一时间动手做多件事情的能力。
并发:线程轮流使用cpu,同一时间应对多件事情的能力。
同步:需要等待结果返回才能继续向下运行
异步:不需要等待结果返回,就能继续向下运行。
//继承Thread类,匿名内部类的写法
Thread t = new Thread("t1") {
@Override
public void run() {
log.info("666");
}
};
t.start();
//实现Runnable接口,lambda表达式的写法
new Thread(()->{
System.out.println("666");
},"t2").start();
//FutureTask异步任务,lambda表达式的写法,Callable函数式接口,有返回值和异常抛出。
FutureTask<Integer> task = new FutureTask<Integer>(()->{
return 100;
});
new Thread(task,"t3").start();
每个线程启动,虚拟机会为其分配线程工作栈内存。每个工作栈内存由多个栈帧组成,对应着每次方法调用时所占用的内存。每个线程只有一个活动栈帧,对应着当前正在执行的方法。
TimeUnit.MILLISECONDS.sleep(500);
public class CpuSleepTest {
public static void main(String[] args) throws InterruptedException {
while (true){
Thread.sleep(1);
System.out.println(new Date());
}
}
}
/**
* The minimum priority that a thread can have.
*/
public final static int MIN_PRIORITY = 1;
/**
* The default priority that is assigned to a thread.
*/
public final static int NORM_PRIORITY = 5;
/**
* The maximum priority that a thread can have.
*/
public final static int MAX_PRIORITY = 10;
public class YieldPriorotyTest {
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
int count = 0;
for (; ; ) {
System.out.println("t1--"+count++);
}
});
Thread t2 = new Thread(() -> {
int count = 0;
for (; ; ) {
//Thread.yield();//礼让
System.out.println(" t2--"+count++);
}
});
t2.start();
t1.start();
//设置线程优先级
t2.setPriority(Thread.MAX_PRIORITY);
t1.setPriority(Thread.MIN_PRIORITY);
}
}
等待调用join()方法的线程结束
package new2023.juc;
import java.util.concurrent.TimeUnit;
/**
* @Author zhangxuhui
* @Date 2023/3/17
* @email [email protected]
*/
public class JoinTest {
static int s = 0;
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(()->{
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
s = 10;
System.out.println("t is over");
},"t");
t.start();
t.join();//插队,等待t线程结束。
System.out.println(s);
}
}
package new2023.juc;
/**
* @Author zhangxuhui
* @Date 2023/3/17
* @email [email protected]
*/
public class InterruptTest {
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(()->{
System.out.println("sleep....");
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("thread is over");
});
t.start();
Thread.sleep(1000);
System.out.println("interrupt...");
t.interrupt();
System.out.println("打断标记:"+t.isInterrupted());//false
}
}
package new2023.juc;
import java.util.concurrent.TimeUnit;
/**
* @Author zhangxuhui
* @Date 2023/3/17
* @email [email protected]
*/
public class InterruptRunningThread {
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(()->{
while(true){
boolean interrupted = Thread.currentThread().isInterrupted();
System.out.println(interrupted);
if(interrupted){
System.out.println("thread is inturrupted : stop");
break;
}
}
});
t.start();
TimeUnit.SECONDS.sleep(1);
t.interrupt();
System.out.println("main thread is stop");
}
}
package new2023.juc;
import java.util.concurrent.TimeUnit;
/**
* @Author zhangxuhui
* @Date 2023/3/17
* @email [email protected]
*/
public class TwoPhaseTermination {
public static void main(String[] args) throws InterruptedException {
Phase p = new Phase();
p.start();
TimeUnit.SECONDS.sleep(3);
p.stop();
System.out.println("等待重启...");
TimeUnit.SECONDS.sleep(5);
p.restart();
}
}
class Phase{
private Thread monitor;
public void start(){
monitor = new Thread(()->{
while (true){
Thread current = Thread.currentThread();
//current.isInterrupted();不会清除打断标记
//Thread.interrupted();会清除打断标记
if(current.isInterrupted()){
System.out.println("线程被打断,料理后事");
break;
}
try {
Thread.sleep(1000);
System.out.println("系统监控");
} catch (InterruptedException e) {
e.printStackTrace();
current.interrupt();
}
}
});
monitor.start();
}
public void stop(){
monitor.interrupt();
}
public void restart(){
start();
}
}
package new2023.juc;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.LockSupport;
/**
* @Author zhangxuhui
* @Date 2023/3/18
* @email [email protected]
*/
public class InterruptPark {
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(()->{
System.out.println("park");
LockSupport.park();
System.out.println("unpark");
// System.out.println(Thread.currentThread().isInterrupted());
System.out.println(Thread.interrupted());//获取打断标记并清除
System.out.println("park two");
LockSupport.park();//打断标记为true时失效
},"t");
t.start();
TimeUnit.SECONDS.sleep(2);
t.interrupt();
}
}
默认情况下,Java进程需要等待所有的线程结束才会结束。有一种特殊的线程叫守护线程,只要其他非守护线程运行结束了,即使守护线程代码没有运行结束也会强行结束。垃圾回收器线程就是守护线程。
package new2023.juc;
import java.util.concurrent.TimeUnit;
/**
* @Author zhangxuhui
* @Date 2023/3/18
* @email [email protected]
*/
public class SetThreadDeamon {
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(() -> {
while (true){
System.out.println("running...");
}
});
thread.setDaemon(true);
thread.start();
TimeUnit.MILLISECONDS.sleep(10);
System.out.println("thread main over");
}
}
package new2023.juc;
/**
* @Author zhangxuhui
* @Date 2023/3/18
* @email [email protected]
*/
public class TeaThread {
public static void main(String[] args) {
Thread t1 = new Thread(()->{
try {
Thread.sleep(1000);
System.out.println("小王 洗水壶");
Thread.sleep(5000);
System.out.println("小王 烧开水");
} catch (InterruptedException e) {
e.printStackTrace();
}
},"小王");
Thread t2 = new Thread(()->{
try {
Thread.sleep(1000);
System.out.println("大王 洗茶壶");
Thread.sleep(1000);
System.out.println("大王 洗茶杯");
Thread.sleep(1000);
System.out.println("大王 拿茶叶");
t1.join();
System.out.println("大王 泡茶");
} catch (InterruptedException e) {
e.printStackTrace();
}
},"大王");
t1.start();
t2.start();
}
}
采用的互斥的方式让同一时刻,至多只有一个线程能持有对象锁,其他线程再想获取这个对象锁时就会阻塞住,这样就能保证拥有锁的线程可以安全的执行临界区内的代码,而不用担心线程的上下文切换导致线程同步问题的出现。
package new2023.juc;
/**
* @Author zhangxuhui
* @Date 2023/3/19
* @email [email protected]
*/
public class synchronizedTest {
static int count=0;
public static void main(String[] args)throws Exception {
Object lock = new Object();
Thread t1 = new Thread(() -> {
for (int i = 0 ; i < 5000 ;i++){
synchronized(lock){
count++;
}
}
});
Thread t2 = new Thread(() -> {
for (int i = 0 ; i < 5000 ;i++){
synchronized (lock) {
count--;
}
}
});
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println(count);
}
}
package new2023.juc;
/**
* @Author zhangxuhui
* @Date 2023/3/19
* @email [email protected]
*/
public class OOMSynchronized {
public static void main(String[] args) throws Exception{
Room room = new Room();
Thread t1 = new Thread(() -> {
for (int i = 0 ; i < 5000 ;i++){
room.incr();
}
});
Thread t2 = new Thread(() -> {
for (int i = 0 ; i < 5000 ;i++){
room.decr();
}
});
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println(room.getCount());
}
}
class Room{
private int count = 0;
public void incr(){
synchronized(this){
count++;
}
}
public void decr(){
synchronized (this){
count--;
}
}
public int getCount(){
synchronized (this){
return count;
}
}
}
class test{
public void t1(){
synchronized (this){
}
}
//等价
public synchronized void t2(){
}
}
class test2{
public synchronized static void t(){
}
//等价
public void t2(){
synchronized (test2.class){
}
}
}
package new2023.juc;
/**
* @Author zhangxuhui
* @Date 2023/3/21
* @email [email protected]
*/
public class AcountTest {
public static void main(String[] args) throws InterruptedException {
Counter a = new Counter(1000);
Counter b = new Counter(1000);
Thread t1 = new Thread(()->{
for (int i = 0; i < 1000; i++) {
a.transfer(b,1);
}
});
Thread t2 = new Thread(()->{
for (int i = 0; i < 1000; i++) {
b.transfer(a,1);
}
});
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println(a.getCount()+ b.getCount());
}
}
class Counter{
private int count;
Counter(int count){
this.count=count;
}
public int getCount(){
return this.count;
}
public void setCount(int count){
this.count = count;
}
public void transfer(Counter target,int money){
//类锁,因为this和target为不同的对象,不能用对象锁。
//他们共同的对象是Counter.class类对象。
synchronized (Counter.class) {
if (this.count >= money) {
this.setCount(this.count - money);
target.setCount(target.count + money);
}
}
}
}
有一个结果需要从一个线程传递到另一个线程,让他们关联同一个guardedobject。jdk中join,future的实现就是采用此模式。
package new2023.保护性暂停;
/**
* @Author zhangxuhui
* @Date 2023/4/5
* @email [email protected]
* 线程传递结果的中间对象
*/
public class GuardeObject {
private Object response;
//get response by timeOut
public Object get(long timeOut){
synchronized (this){
long start = System.currentTimeMillis();
long con = 0;
while (response == null){
long waitTime = timeOut - con;
if (waitTime <= 0){
break;
}
try {
this.wait(waitTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
con = System.currentTimeMillis() - start;
}
return response;
}
}
//get response
public Object get(){
synchronized (this){
while (response == null){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return response;
}
}
//set response
public void complete(Object o){
synchronized (this){
this.response = o;
this.notifyAll();
}
}
}
package new2023.生产者消费者模式;
import java.util.LinkedList;
/**
* @Author zhangxuhui
* @Date 2023/4/5
* @email [email protected]
* 消息队列
*/
public class MessageQuene {
private LinkedList<Message> list = new LinkedList<>();
private int cap;
public MessageQuene(int cap) {
this.cap = cap;
}
public Message take(){
synchronized (list){
while (list.isEmpty()){
try {
System.out.println(Thread.currentThread().getName()+"队列为空,没有消息。");
list.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Message last = list.removeLast();
System.out.println(Thread.currentThread().getName()+"消费消息:"+last);
list.notifyAll();
return last;
}
}
public void put(Message msg){
synchronized (list){
while (list.size() == cap){
try {
System.out.println(Thread.currentThread().getName()+"队列已满");
list.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
list.addFirst(msg);
System.out.println(Thread.currentThread().getName()+"生产消息:"+msg);
list.notifyAll();
}
}
}
package new2023.生产者消费者模式;
/**
* @Author zhangxuhui
* @Date 2023/4/5
* @email [email protected]
*/
public class TestMessage {
public static void main(String[] args) {
MessageQuene quene = new MessageQuene(2);
for (int i = 0; i < 3; i++) {
int id = i;
new Thread(()->{
quene.put(new Message(id,"msg"+id));
}).start();
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(()->{
for (;;){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
quene.take();
}
}).start();
}
}
package new2023.juc;
/**
* @Author zhangxuhui
* @Date 2023/4/6
* @email [email protected]
* 实际开发中应避免死锁的产生
*/
public class ThreadDeadLock {
public static void main(String[] args) {
Object locka = new Object();
Object lockb = new Object();
new Thread(()->{
synchronized (locka){
System.out.println("locka--" + Thread.currentThread().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (lockb){
System.out.println("lockb--"+Thread.currentThread().getName());
}
}
},"t1").start();
new Thread(()->{
synchronized (lockb){
System.out.println("lockb--" + Thread.currentThread().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (locka){
System.out.println("locka--"+Thread.currentThread().getName());
}
}
},"t2").start();
}
}
相对于synchronized对比具有以下特点:
package new2023.juc;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
/**
* @Author zhangxuhui
* @Date 2023/4/7
* @email [email protected]
* await前先获得锁
* await执行后释放锁,进入condition对象等待。
* await被唤醒/打断/超时后会重新竞争锁
* 竞争锁成功后将继续执行
*/
public class ReentantLockCondationTest {
static ReentrantLock lock = new ReentrantLock();
static Condition room = lock.newCondition();
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
lock.lock();
try {
System.out.println("go into room");
try {
room.await();
System.out.println("run..");
} catch (InterruptedException e) {
e.printStackTrace();
}
}finally {
lock.unlock();
}
}, "t1");
t1.start();
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
lock.lock();
try {
System.out.println("唤醒。。。");
room.signal();
}finally {
lock.unlock();
}
}
}
package new2023.juc;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
/**
* @Author zhangxuhui
* @Date 2023/4/8
* @email [email protected]
*/
public class ControlPrintNumReentrantLock {
public static void main(String[] args) throws InterruptedException {
awaitSinglePrint asp = new awaitSinglePrint();
Condition a = asp.newCondition();
Condition b = asp.newCondition();
Condition c = asp.newCondition();
new Thread(()->{
asp.print("a",a,b);
}).start();
new Thread(()->{
asp.print("b",b,c);
}).start();
new Thread(()->{
asp.print("c",c,a);
}).start();
Thread.sleep(1000);
asp.lock();
try {
a.signal();
}finally {
asp.unlock();
}
}
}
class awaitSinglePrint extends ReentrantLock{
private int loopNum = 5;
public void print(String msg,Condition current,Condition next){
lock();
try {
for (int i = 0; i < loopNum; i++) {
try {
current.await();
System.out.print(msg);
next.signal();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}finally {
unlock();
}
}
}
package new2023.内存模型;
/**
* @Author zhangxuhui
* @Date 2023/4/8
* @email [email protected]
*/
public class BlakingTest {
static volatile boolean flag = false;
public static void main(String[] args) {
Thread thread = new Thread(() -> {
synchronized (BlakingTest.class) {
if (flag) {
System.out.println("stop");
return;
}
flag = true;
System.out.println("start");
}
});
flag = true;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
thread.start();
}
}
package new2023.内存模型;
/**
* @Author zhangxuhui
* @Date 2023/4/8
* @email [email protected]
*/
public class DoubleCheckingLock {
public static void main(String[] args) {
for (int x = 0 ; x < 1000; x++){
new Thread(()->{
System.out.println(DCL.getIns());
}).start();
}
}
}
class DCL{
private static volatile DCL ins = null;
private DCL(){}
public static DCL getIns(){
if(ins == null){
synchronized (DCL.class){
if(ins == null){
ins = new DCL();
}
}
}
return ins;
}
@Override
public String toString() {
return "DCL " + this.hashCode();
}
}
package juc;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
/**
* @Author zhangxuhui
* @Date 2023/4/9
* @email [email protected]
*/
public class AtomicIntergerTest {
public static void main(String[] args) {
AtomicInteger ai = new AtomicInteger(100);
for (int x = 0;x < 10;x++){
new Thread(()->{
while (true){
int i = ai.get();
int update = i - 10;
if(ai.compareAndSet(i,update)){
System.out.println(Thread.currentThread().getName()+"将:"+i+"更新为:"+update);
break;
}
}
}).start();
}
try {
TimeUnit.SECONDS.sleep(1);
System.out.println("最后结果为:"+ai.get());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
package juc;
import java.math.BigDecimal;
import java.util.concurrent.atomic.AtomicReference;
/**
* @Author zhangxuhui
* @Date 2023/4/9
* @email [email protected]
*/
public class AtomicReferenceTest {
public static void main(String[] args) {
BigDecimal bigDecimal = new BigDecimal(100);
AtomicReference<BigDecimal> arf = new AtomicReference(bigDecimal);
System.out.println(arf.get());
if(arf.compareAndSet(bigDecimal,BigDecimal.valueOf(90))){
System.out.println(arf.get());
}
}
}
package juc;
import java.util.concurrent.atomic.AtomicMarkableReference;
/**
* @Author zhangxuhui
* @Date 2022/8/1
* @email [email protected]
*/
public class AtomicMarkableReferenceDemo {
public static void main(String[] args) {
//原子类+标记 默认为false,修改后设置为true。
AtomicMarkableReference<Integer> ar = new AtomicMarkableReference<>(100,false);
boolean marked = ar.isMarked();
System.out.println(marked);
ar.compareAndSet(100,200,marked,!marked);
System.out.println(ar.isMarked());
System.out.println(ar.getReference());
}
}
package new2023.juc;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicIntegerArray;
/**
* @Author zhangxuhui
* @Date 2023/4/9
* @email [email protected]
*/
public class AtomicArrayTest {
public static void main(String[] args) {
// AtomicReferenceArray
// AtomicLongArray
// AtomicIntegerArray
int [] arr = new int[10];
for (int x = 0 ; x < arr.length;x++){
new Thread(()->{
for (int y = 0 ; y < 10000;y++){
arr[y%arr.length] = arr[y%arr.length]+1;
}
}).start();
}
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Arrays.toString(arr));
AtomicIntegerArray ata = new AtomicIntegerArray(10);
for (int x = 0 ; x < ata.length();x++){
new Thread(()->{
for (int y = 0 ; y < 10000;y++){
ata.getAndIncrement(y%ata.length());
}
}).start();
}
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(ata);
}
}
package new2023.juc;
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
/**
* @Author zhangxuhui
* @Date 2023/4/9
* @email [email protected]
* 原子字段更新器
*/
public class AtomicFileUpdateTest {
public static void main(String[] args) {
// AtomicReferenceFieldUpdater
// AtomicIntegerFieldUpdater
// AtomicLongFieldUpdater
Student s = new Student();
AtomicReferenceFieldUpdater arfu = AtomicReferenceFieldUpdater.newUpdater(Student.class,String.class,"name");
arfu.compareAndSet(s,null,"zhangsan");
System.out.println(s);
}
}
class Student{
volatile String name;
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
'}';
}
}
package new2023.juc;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.LongAdder;
/**
* @Author zhangxuhui
* @Date 2023/4/9
* @email [email protected]
*/
public class AtomicNumberAdder {
public static void main(String[] args) {
LongAdder la = new LongAdder();
CountDownLatch cdl = new CountDownLatch(10);
for (int x = 0 ; x < 10;x++){
new Thread(()->{
for(int y = 0 ; y < 20000000;y++){
la.increment();
}
cdl.countDown();
}).start();
}
try {
cdl.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(la.intValue());
}
}
package new2023.juc;
import sun.misc.Unsafe;
import java.lang.reflect.Field;
/**
* @Author zhangxuhui
* @Date 2023/4/9
* @email [email protected]
*/
public class UnsafeTest {
public static void main(String[] args)throws Exception {
Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
theUnsafe.setAccessible(true);
Unsafe unsafe = (Unsafe) theUnsafe.get(null);
Person p = new Person();
Field id = p.getClass().getDeclaredField("id");
Field name = p.getClass().getDeclaredField("name");
long idoffset = unsafe.objectFieldOffset(id);
long nameoffest = unsafe.objectFieldOffset(name);
unsafe.compareAndSwapInt(p,idoffset,0,1);
unsafe.compareAndSwapObject(p,nameoffest,null,"bob");
System.out.println(p);
}
}
class Person{
private volatile String name;
private volatile int id;
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", id=" + id +
'}';
}
}
//读取缓存-128 - 127
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
//String类,不可变类。
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
/** The value is used for character storage. */
private final char value[];
/** Cache the hash code for the string */
private int hash; // Default to 0
}