线程进程、内核态用户态转换,为何转换、系统中断、内核态的多线程是如何通过轻量级实现的。结合自己理解融入到Java线程中
寄存器可被存储线程的局部变量,但是不能其他线程的相关变量
Java采用单线程编程模型,
package thread;
/**
* @Author bennyrhys
* @Date 2020-03-26 21:50
*/
public class CurrentThreadDemo {
public static void main(String[] args) {
System.out.println(Thread.currentThread().getName());
}
}
thread.CurrentThreadDemo main
package thread;
/**
* @Author bennyrhys
* @Date 2020-03-26 22:17
*/
public class ThreadTest {
public static void attack() {
System.out.println("Fight");
System.out.println("attack is :"+ Thread.currentThread().getName());
}
public static void main(String[] args) {
Thread t = new Thread(){
@Override
public void run() {
attack();
}
};
System.out.println(Thread.currentThread().getName()); // main
// t.run(); // main
t.start(); // attack is :Thread-0
}
}
main Fight attack is :Thread-0
新线程由start创建
创建一个新的线程
创建一个线程去run方法名称
Thread类 Runnable接口
Runnable只有一个run抽象方法,说明此接口并不具备多线程的特性. 是依赖Thread里面的star方法在去调用run方法实现多线程
多线程同时遍历
package thread;
/**
* 继承线程
* @Author bennyrhys
* @Date 2020-03-27 18:53
*/
public class MyThread extends Thread{
private String name;
public MyThread(String name) {
this.name = name;
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("This is "+i+" Thread:" + this.name);
}
}
}
package thread;
/**
* @Author bennyrhys
* @Date 2020-03-27 18:56
*/
public class MyThreadMain {
public static void main(String[] args) {
new MyThread("THREAD1").start();
new MyThread("THREAD2").start();
new MyThread("THREAD3").start();
}
}
package thread;
/**
* @Author bennyrhys
* @Date 2020-03-27 19:20
*/
public class MyRunnalbe implements Runnable{
private String name;
public MyRunnalbe(String name) {
this.name = name;
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("This is "+i+" Thread:" + this.name);
}
}
}
package thread;
/**
* @Author bennyrhys
* @Date 2020-03-27 19:21
*/
public class MyRunnableMain {
public static void main(String[] args) {
// 通过Thread的start()方法实现Runable的多线程
MyRunnalbe thread1 = new MyRunnalbe("Thread1");
Thread t1 = new Thread(thread1);
t1.start();
MyRunnalbe thread2 = new MyRunnalbe("Thread2");
Thread t2 = new Thread(thread2);
t2.start();
MyRunnalbe thread3 = new MyRunnalbe("Thread3");
Thread t3 = new Thread(thread3);
t3.start();
}
}
跟线程相关的业务逻辑放在run()方法,但是run()方法没有参数也没有返回值的。 主要三种: 构造函数传参(上边用过) 成员变量传参(setName) 回调函数传参
在这里插入图片描述
自己实现循环等待逻辑,需要循环等待的多,代码变得臃肿 循环多久不确定,无法精准控制
package thread;
/**
* @Author bennyrhys
* @Date 2020-03-27 20:49
*/
public class CycleWait implements Runnable{
private String value;
@Override
public void run() {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
value = "we have data now";
}
public static void main(String[] args) throws InterruptedException {
CycleWait cw = new CycleWait();
Thread t = new Thread(cw);
t.start();
// 主线程等待法
while (cw.value == null) {
Thread.sleep(100);
}
// 未加等待法 null, 加了等待法 we have data now
System.out.println(cw.value);
}
}
比主线程等待法实现更简单 控制更精准 t.join();
实现粒度低。 【无法同时多个线程的run()实现】
package thread;
/**
* @Author bennyrhys
* @Date 2020-03-27 20:49
*/
public class CycleWait implements Runnable{
private String value;
@Override
public void run() {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
value = "we have data now";
}
public static void main(String[] args) throws InterruptedException {
CycleWait cw = new CycleWait();
Thread t = new Thread(cw);
t.start();
// // 主线程等待法
// while (cw.value == null) {
// Thread.sleep(100);
// }
// join法阻塞当前线程执行后执行 we have data now
t.join();
// 未加等待法 null, 加了等待法 we have data now
System.out.println(cw.value);
}
}
线程池实现提交多个Callable的类,去让线程池并发的处理结果。 统一对Callable的类进行统一的管理
package thread;
import java.util.concurrent.Callable;
/**
* @Author bennyrhys
* @Date 2020-03-27 21:26
*/
public class MyCallable implements Callable<String> {
@Override
public String call() throws Exception {
String value = "test";
System.out.println("Ready to work");
Thread.sleep(5000);
System.out.println("task done");
return value;
}
}
package thread;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
/**
FutrueTask接收
* @Author bennyrhys
* @Date 2020-03-27 21:34
*/
public class MyCallableMain {
public static void main(String[] args) throws ExecutionException, InterruptedException {
FutureTask<String> task = new FutureTask<>(new MyCallable());
new Thread(task).start();
if (!task.isDone()) {
System.out.println("task has not finished, please wait");
}
System.out.println("task return" + task.get());
}
}
task has not finished, please wait Ready to work(五秒后) task done task returntest
package thread;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
/**
* 线程池接收
* @Author bennyrhys
* @Date 2020-03-27 21:56
*/
public class ThreadPoolDemo {
public static void main(String[] args) {
// 创建线程池
ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();
Future<String> future = newCachedThreadPool.submit(new MyCallable());
if (!future.isDone()) {
System.out.println("task has not finished, please wait!");
}
try {
System.out.println(future.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} finally {
// 关闭线程池
newCachedThreadPool.shutdown();
}
}
}
task has not finished, please wait! Ready to work task done test
接收的FutrueTask->Runnable FutrueTask实现的方法
线程池
新建:未start() 运行:调用了start(),Ready获得cpu的使用时间后->Running 无限期等待:需要被显示的唤醒,nodef 结束:线程一旦终止不能复生。终止的再调start()会抛异常
wait()唤醒阻塞, 即使不传参,调用的也是带参数的,无限期等待
package thread;
/**
* @Author bennyrhys
* @Date 2020-03-28 16:05
* 先锁定的状态
* Thread A is waiting to get lock
* Thread A get lock
* Thread B is waiting to get lock
* Thread A do wait method
* Thread B get lock
* Thread B is sleeping 10ms
* Thread B is done
* Thread A is done
*
* 翻转情况-a不释放锁,一直到执行完毕
* Thread A is waiting to get lock
* Thread A get lock
* Thread B is waiting to get lock
* Thread A do wait method
* Thread A is done
* Thread B get lock
* Thread B is sleeping 10ms
* Thread B is done
*/
public class WaitSleepDemo {
public static void main(String[] args) {
// wait()必须由Object创建
final Object lock = new Object();
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Thread A is waiting to get lock");
synchronized (lock) {
try {
System.out.println("Thread A get lock");
Thread.sleep(20);
System.out.println("Thread A do wait method");
Thread.sleep(1000);
// lock.wait(1000);
System.out.println("Thread A is done");
}catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
// 强制上方线程先执行
try {
Thread.sleep(10);
}catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Thread B is waiting to get lock");
synchronized (lock) {
try {
System.out.println("Thread B get lock");
System.out.println("Thread B is sleeping 10ms");
lock.wait(10);
// Thread.sleep(10);
System.out.println("Thread B is done");
}catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
}
package thread;
/**
* @Author bennyrhys
* @Date 2020-03-28 16:05
* 先锁定的状态
* Thread A is waiting to get lock
* Thread A get lock
* Thread B is waiting to get lock
* Thread A do wait method
* Thread B get lock
* Thread B is sleeping 10ms
* Thread B is done
* Thread A is done
*
* 翻转情况-a不释放锁,一直到执行完毕
* Thread A is waiting to get lock
* Thread A get lock
* Thread B is waiting to get lock
* Thread A do wait method
* Thread A is done
* Thread B get lock
* Thread B is sleeping 10ms
* Thread B is done
*/
public class WaitSleepDemo {
public static void main(String[] args) {
// wait()必须由Object创建
final Object lock = new Object();
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Thread A is waiting to get lock");
synchronized (lock) {
try {
System.out.println("Thread A get lock");
Thread.sleep(20);
System.out.println("Thread A do wait method");
// Thread.sleep(1000);
lock.wait(); // 进入无限的等待当中
System.out.println("Thread A is done");
}catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
// 强制上方线程先执行
try {
Thread.sleep(10);
}catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Thread B is waiting to get lock");
synchronized (lock) {
try {
System.out.println("Thread B get lock");
System.out.println("Thread B is sleeping 10ms");
// lock.wait(10);
Thread.sleep(10);
System.out.println("Thread B is done");
lock.notifyAll(); // 用其他线程 唤醒沉睡的线程
}catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
}
多线程抢占锁,如果某对象没有竞争到锁,只会留在锁池中,不会在等待池中
import java.util.logging.Level;
import java.util.logging.Logger;
public class NotificationDemo {
private volatile boolean go = false;
public static void main(String args[]) throws InterruptedException {
final NotificationDemo test = new NotificationDemo();
Runnable waitTask = new Runnable(){
@Override
public void run(){
try {
test.shouldGo();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " finished Execution");
}
};
Runnable notifyTask = new Runnable(){
@Override
public void run(){
test.go();
System.out.println(Thread.currentThread().getName() + " finished Execution");
}
};
Thread t1 = new Thread(waitTask, "WT1"); //will wait
Thread t2 = new Thread(waitTask, "WT2"); //will wait
Thread t3 = new Thread(waitTask, "WT3"); //will wait
Thread t4 = new Thread(notifyTask,"NT1"); //will notify
//starting all waiting thread
t1.start();
t2.start();
t3.start();
//pause to ensure all waiting thread started successfully
Thread.sleep(200);
//starting notifying thread
t4.start();
}
/*
* wait and notify can only be called from synchronized method or bock
*/
private synchronized void shouldGo() throws InterruptedException {
while(go != true){
System.out.println(Thread.currentThread()
+ " is going to wait on this object");
wait(); //release lock and reacquires on wakeup
System.out.println(Thread.currentThread() + " is woken up");
}
go = false; //resetting condition
}
/*
* both shouldGo() and go() are locked on current object referenced by "this" keyword
*/
private synchronized void go() {
while (go == false){
System.out.println(Thread.currentThread()
+ " is going to notify all or one thread waiting on this object");
go = true; //making condition true for waiting thread
//notify(); // only one out of three waiting thread WT1, WT2,WT3 will woke up
notifyAll(); // all waiting thread WT1, WT2,WT3 will woke up
}
}
}
public class YieldDemo {
public static void main(String[] args) {
Runnable yieldTask = new Runnable() {
@Override
public void run() {
for (int i = 1; i <= 10; i++) {
System.out.println(Thread.currentThread().getName() + i);
if (i == 5) {
Thread.yield();
}
}
}
};
Thread t1 = new Thread(yieldTask, "A");
Thread t2 = new Thread(yieldTask, "B");
t1.start();
t2.start();
}
}
到5切换线程,接受暗示
到5不切换线程,忽略暗示
stop()一个线程,调用另一个线程停止。 这种不妥,未知另一个状态,导致线程无法清理完成释,放锁,数据异常。
public class InterruptDemo {
public static void main(String[] args) throws InterruptedException {
Runnable interruptTask = new Runnable() {
@Override
public void run() {
int i = 0;
try {
//在正常运行任务时,经常检查本线程的中断标志位,如果被设置了中断标志就自行停止线程
while (!Thread.currentThread().isInterrupted()) {
Thread.sleep(100); // 休眠100ms
i++;
System.out.println(Thread.currentThread().getName() + " (" + Thread.currentThread().getState() + ") loop " + i);
}
} catch (InterruptedException e) {
//在调用阻塞方法时正确处理InterruptedException异常。(例如,catch异常后就结束线程。)
System.out.println(Thread.currentThread().getName() + " (" + Thread.currentThread().getState() + ") catch InterruptedException.");
}
}
};
Thread t1 = new Thread(interruptTask, "t1");
System.out.println(t1.getName() +" ("+t1.getState()+") is new.");
t1.start(); // 启动“线程t1”
System.out.println(t1.getName() +" ("+t1.getState()+") is started.");
// 主线程休眠300ms,然后主线程给t1发“中断”指令。
Thread.sleep(300);
t1.interrupt();
System.out.println(t1.getName() +" ("+t1.getState()+") is interrupted.");
// 主线程休眠300ms,然后查看t1的状态。
Thread.sleep(300);
System.out.println(t1.getName() +" ("+t1.getState()+") is interrupted now.");
}
}