目录
线程与进程
windows下查CPU信息
Thread类实现多线程
错误的代码🤣
直接调用run()方法是错误的!!!
class MyThread extends Thread { // 定义线程主体类
private String name;
public MyThread(String name) { // 设置一个名称
this.name = name;
}
@Override // 覆写父类中的方法
public void run() { // 线程运行的主方法
for (int x = 0; x < 10; x++) {
System.out.println("【" + this.name + "】线程执行,当前的循环次数为:x = " + x);
}
}
}
public class A01错误的线程写法 {
public static void main(String[] args) {
MyThread threadA = new MyThread("Yootk-A线程"); // 线程类对象
MyThread threadB = new MyThread("Yootk-B线程"); // 线程类对象
MyThread threadC = new MyThread("Yootk-C线程"); // 线程类对象
threadA.run(); // 线程主方法
threadB.run(); // 线程主方法
threadC.run(); // 线程主方法
}
}
运行结果:
【Yootk-A线程】线程执行,当前的循环次数为:x = 0
【Yootk-A线程】线程执行,当前的循环次数为:x = 1
【Yootk-A线程】线程执行,当前的循环次数为:x = 2
【Yootk-A线程】线程执行,当前的循环次数为:x = 3
【Yootk-A线程】线程执行,当前的循环次数为:x = 4
【Yootk-A线程】线程执行,当前的循环次数为:x = 5
【Yootk-A线程】线程执行,当前的循环次数为:x = 6
【Yootk-A线程】线程执行,当前的循环次数为:x = 7
【Yootk-A线程】线程执行,当前的循环次数为:x = 8
【Yootk-A线程】线程执行,当前的循环次数为:x = 9
【Yootk-B线程】线程执行,当前的循环次数为:x = 0
【Yootk-B线程】线程执行,当前的循环次数为:x = 1
【Yootk-B线程】线程执行,当前的循环次数为:x = 2
【Yootk-B线程】线程执行,当前的循环次数为:x = 3
【Yootk-B线程】线程执行,当前的循环次数为:x = 4
【Yootk-B线程】线程执行,当前的循环次数为:x = 5
【Yootk-B线程】线程执行,当前的循环次数为:x = 6
【Yootk-B线程】线程执行,当前的循环次数为:x = 7
【Yootk-B线程】线程执行,当前的循环次数为:x = 8
【Yootk-B线程】线程执行,当前的循环次数为:x = 9
【Yootk-C线程】线程执行,当前的循环次数为:x = 0
【Yootk-C线程】线程执行,当前的循环次数为:x = 1
【Yootk-C线程】线程执行,当前的循环次数为:x = 2
【Yootk-C线程】线程执行,当前的循环次数为:x = 3
【Yootk-C线程】线程执行,当前的循环次数为:x = 4
【Yootk-C线程】线程执行,当前的循环次数为:x = 5
【Yootk-C线程】线程执行,当前的循环次数为:x = 6
【Yootk-C线程】线程执行,当前的循环次数为:x = 7
【Yootk-C线程】线程执行,当前的循环次数为:x = 8
【Yootk-C线程】线程执行,当前的循环次数为:x = 9
正确的写法
public static void main(String[] args) {
MyThread threadA = new MyThread("Yootk-A线程"); // 线程类对象
MyThread threadB = new MyThread("Yootk-B线程"); // 线程类对象
MyThread threadC = new MyThread("Yootk-C线程"); // 线程类对象
threadA.start(); // 启动线程并调用run()方法
threadB.start(); // 启动线程并调用run()方法
threadC.start(); // 启动线程并调用run()方法
}
运行结果:
【Yootk-B线程】线程执行,当前的循环次数为:x = 0
【Yootk-C线程】线程执行,当前的循环次数为:x = 0
【Yootk-A线程】线程执行,当前的循环次数为:x = 0
【Yootk-A线程】线程执行,当前的循环次数为:x = 1
【Yootk-C线程】线程执行,当前的循环次数为:x = 1
【Yootk-C线程】线程执行,当前的循环次数为:x = 2
【Yootk-C线程】线程执行,当前的循环次数为:x = 3
【Yootk-C线程】线程执行,当前的循环次数为:x = 4
【Yootk-C线程】线程执行,当前的循环次数为:x = 5
【Yootk-C线程】线程执行,当前的循环次数为:x = 6
【Yootk-C线程】线程执行,当前的循环次数为:x = 7
【Yootk-C线程】线程执行,当前的循环次数为:x = 8
【Yootk-C线程】线程执行,当前的循环次数为:x = 9
【Yootk-B线程】线程执行,当前的循环次数为:x = 1
【Yootk-B线程】线程执行,当前的循环次数为:x = 2
【Yootk-A线程】线程执行,当前的循环次数为:x = 2
【Yootk-A线程】线程执行,当前的循环次数为:x = 3
【Yootk-B线程】线程执行,当前的循环次数为:x = 3
【Yootk-B线程】线程执行,当前的循环次数为:x = 4
【Yootk-B线程】线程执行,当前的循环次数为:x = 5
【Yootk-A线程】线程执行,当前的循环次数为:x = 4
【Yootk-A线程】线程执行,当前的循环次数为:x = 5
【Yootk-A线程】线程执行,当前的循环次数为:x = 6
【Yootk-A线程】线程执行,当前的循环次数为:x = 7
【Yootk-A线程】线程执行,当前的循环次数为:x = 8
【Yootk-A线程】线程执行,当前的循环次数为:x = 9
【Yootk-B线程】线程执行,当前的循环次数为:x = 6
【Yootk-B线程】线程执行,当前的循环次数为:x = 7
【Yootk-B线程】线程执行,当前的循环次数为:x = 8
【Yootk-B线程】线程执行,当前的循环次数为:x = 9
Runnable
class MyThread implements Runnable { // 定义线程主体类
private String name ;
public MyThread(String name) { // 设置一个名称
this.name = name ;
}
@Override // 覆写父类中的方法
public void run() { // 线程运行的主方法
for (int x = 0 ; x < 1000 ; x ++) {
System.out.println("【" + this.name + "】线程执行,当前的循环次数为:x = " + x);
}
}
}
public class Runnable多线程 {
public static void main(String[] args) {
MyThread threadA = new MyThread("Yootk-A线程") ; // 线程类对象
MyThread threadB = new MyThread("Yootk-B线程") ; // 线程类对象
MyThread threadC = new MyThread("Yootk-C线程") ; // 线程类对象
new Thread(threadA).start(); // 启动线程并调用run()方法
new Thread(threadB).start(); // 启动线程并调用run()方法
new Thread(threadC).start(); // 启动线程并调用run()方法
}
}
Lambda写法
public class Lambda简写 {
public static void main(String[] args) {
for (int x = 0 ; x < 3 ; x ++) {
String name = "Yootk-" + x + "线程对象" ;
new Thread(()->{
for (int y = 0 ; y < 10 ; y ++) {
System.out.println("【" + name + "】线程执行,当前的循环次数为:num = " + y);
}
}).start(); // 启动多线程
}
}
}
这种写法简单多了,就感觉跟写ES6语法差不多。
Runnable与Thread的关系
卖票程序演示
package com.yootk.demo;
class MyThread implements Runnable { // 定义线程主体类
private int ticket = 5 ; // 一共要卖5张票
@Override // 覆写父类中的方法
public void run() { // 线程运行的主方法
while (this.ticket > 0) { // 编写一个循环
if (this.ticket > 0) { // 判断是否有剩余的票数
System.out.println("【卖票】ticket = " + this.ticket --); // 卖票处理
} else { // 结束循环
break ;
}
}
}
}
public class YootkDemo { // 李兴华编程训练营:yootk.ke.qq.com
public static void main(String[] args) {
MyThread myThread = new MyThread() ; // 创建Runnable接口对象
// Runnable如果要想进行启动则必须依靠Thread类,而在Thread类里面提供有一个target的属性。
Thread threadA = new Thread(myThread) ; // 创建Thread类的对象实例
Thread threadB = new Thread(myThread) ; // 创建Thread类的对象实例
Thread threadC = new Thread(myThread) ; // 创建Thread类的对象实例
threadA.start(); // 启动多线程,所有的操作都针对于同一个target对象实例完成
threadB.start(); // 启动多线程,所有的操作都针对于同一个target对象实例完成
threadC.start(); // 启动多线程,所有的操作都针对于同一个target对象实例完成
}
}
Thread方式实现
package com.yootk.demo;
class MyThread extends Thread { // 定义线程主体类
private int ticket = 5 ; // 一共要卖5张票
@Override // 覆写父类中的方法
public void run() { // 线程运行的主方法
while (this.ticket > 0) { // 编写一个循环
if (this.ticket > 0) { // 判断是否有剩余的票数
System.out.println("【卖票】ticket = " + this.ticket --); // 卖票处理
} else { // 结束循环
break ;
}
}
}
}
public class YootkDemo { // 李兴华编程训练营:yootk.ke.qq.com
public static void main(String[] args) {
MyThread myThread = new MyThread() ; // 创建Runnable接口对象
// Runnable如果要想进行启动则必须依靠Thread类,而在Thread类里面提供有一个target的属性。
Thread threadA = new Thread(myThread) ; // 创建Thread类的对象实例
Thread threadB = new Thread(myThread) ; // 创建Thread类的对象实例
Thread threadC = new Thread(myThread) ; // 创建Thread类的对象实例
threadA.start(); // 启动多线程,所有的操作都针对于同一个target对象实例完成
threadB.start(); // 启动多线程,所有的操作都针对于同一个target对象实例完成
threadC.start(); // 启动多线程,所有的操作都针对于同一个target对象实例完成
}
}
Callable
package com.yootk.demo;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
import java.util.concurrent.RunnableFuture;
class MyThread implements Callable<String> { // 返回值类型为String
@Override // 覆写父类中的方法
public String call() { // 线程运行的主方法
String result = "" ; // 保存返回结果
for (int x = 0 ; x < 10 ; x ++) { // 执行一个数据的循环操作
result += "沐言科技:www.yootk.com\n" ; // 循环修改字符串内容,不去考虑性能问题
}
return result ;
}
}
public class YootkDemo { // 李兴华编程训练营:yootk.ke.qq.com
public static void main(String[] args) throws Exception {
MyThread myThread = new MyThread() ; // 创建Callable接口对象
FutureTask<String> future = new FutureTask<>(myThread) ; // 包装了Callable接口对象
Thread thread = new Thread(future) ; // 通过Thread创建线程对象
thread.start(); // 启动多线程
System.out.println(future.get()); // 异步获取
}
}
运行结果:
沐言科技:www.yootk.com
沐言科技:www.yootk.com
沐言科技:www.yootk.com
沐言科技:www.yootk.com
沐言科技:www.yootk.com
沐言科技:www.yootk.com
沐言科技:www.yootk.com
沐言科技:www.yootk.com
沐言科技:www.yootk.com
沐言科技:www.yootk.com
什么是JUC
生命周期
线程的休眠
package com.yootk.demo;
public class YootkDemo { // 李兴华编程训练营:yootk.ke.qq.com
public static void main(String[] args) throws Exception {
for (int x = 0; x < 10; x++) {
new Thread(() -> {
for (int y = 0; y < 100; y++) {
try {
Thread.sleep(1000); // 延迟1秒执行
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("【" + Thread.currentThread().getName() + "】num = " + y);
}
}, "Yootk线程 - " + x).start(); // 线程启动
}
}
}
线程中断
package com.yootk.demo;
public class YootkDemo { // 李兴华编程训练营:yootk.ke.qq.com
public static void main(String[] args) throws Exception {
Thread thread = new Thread(()->{
try {
System.out.println("【"+Thread.currentThread().getName()+"】准备进入到休眠状态,预计的休眠时间为20秒 ...");
Thread.sleep(20000); // 需要休眠20秒的时间
System.out.println("【"+Thread.currentThread().getName()+"】休眠状态正常结束 ...");
} catch (InterruptedException e) { // 线程被中断就会产生中断异常
System.out.println("【"+Thread.currentThread().getName()+"】休眠产生了异常,无法正常完成休眠处理 ...");
}
}, "休眠线程") ; // 创建一个线程类
thread.start(); // 启动多线程
System.out.println("【中断状态】" + thread.isInterrupted());
Thread.sleep(2000); // 让线程对象适当的执行一段时间
thread.interrupt(); // 打断当前线程的休眠状态
System.out.println("【中断状态】" + thread.isInterrupted());
}
}
线程的强制执行
package com.yootk.demo;
public class YootkDemo { // 李兴华编程训练营:yootk.ke.qq.com
public static void main(String[] args) throws Exception {
Thread mainThread = Thread.currentThread(); // 获取当前的主线程
Thread joinThread = new Thread(() -> {
for (int x = 0; x < 10000; x++) { // 将持续执行循环代码
try {
Thread.sleep(100); // 追加一个延迟
if (x >= 10) { // 设置一个处理条件
mainThread.join(); // 子线程要交出全部的资源给主线程
}
System.out.println("〖" + Thread.currentThread().getName() + "〗子线程执行,x = " + x);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "工作线程"); // 创建一个线程类
joinThread.start(); // 启动子线程
for (int x = 0; x < 30; x++) {
Thread.sleep(100); // 追加一个延迟
System.out.println("【" + Thread.currentThread().getName() + "】主线程执行,x = " + x);
}
}
}
线程同步
线程死锁
生产者与消费者模型
生产者与消费者模型的实现类结构
package com.yootk.demo;
class Message { // 描述一个公共空间
private String title ; // 描述信息的标题
private String content ; // 描述信息的内容
public void setTitle(String title) {
this.title = title;
}
public void setContent(String content) {
this.content = content;
}
public String getTitle() {
return title;
}
public String getContent() {
return content;
}
}
class ProducerThread implements Runnable {
private Message message ; // 获取Message的引用
public ProducerThread(Message message) {
this.message = message ;
}
@Override
public void run() {
for (int x = 0 ; x < 50 ; x ++) { // 生产50次的信息
try {
if (x % 2 == 0) {
this.message.setTitle("李兴华编程训练营");
Thread.sleep(100);
this.message.setContent("yootk.ke.qq.com");
} else {
this.message.setTitle("沐言科技");
Thread.sleep(100);
this.message.setContent("www.yootk.com");
}
} catch (Exception e) {}
}
}
}
class ConsumerThread implements Runnable {
private Message message ; // 获取Message的引用
public ConsumerThread(Message message) {
this.message = message ;
}
@Override
public void run() {
for (int x = 0 ; x < 50 ; x ++) { // 获取50次的信息
System.out.println("【消费者】title = " + this.message.getTitle() + "、content = " + this.message.getContent());
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class YootkDemo { // 李兴华编程训练营:yootk.ke.qq.com
public static void main(String[] args) throws Exception {
Message message = new Message() ; // 实例化Message
new Thread(new ProducerThread(message)).start(); // 启动生产者线程
new Thread(new ConsumerThread(message)).start(); // 启动消费者线程
}
}
数据同步处理
package com.yootk.demo;
class Message { // 描述一个公共空间
private String title ; // 描述信息的标题
private String content ; // 描述信息的内容
public synchronized void set(String title, String content) {
this.title = title ;
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.content = content ;
}
public synchronized String get() {
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "title = " + this.title + "、content = " + this.content ;
}
}
class ProducerThread implements Runnable {
private Message message ; // 获取Message的引用
public ProducerThread(Message message) {
this.message = message ;
}
@Override
public void run() {
for (int x = 0 ; x < 50 ; x ++) { // 生产50次的信息
try {
if (x % 2 == 0) {
this.message.set("李兴华编程训练营", "yootk.ke.qq.com");
} else {
this.message.set("沐言科技", "www.yootk.com");
}
} catch (Exception e) {}
}
}
}
class ConsumerThread implements Runnable {
private Message message ; // 获取Message的引用
public ConsumerThread(Message message) {
this.message = message ;
}
@Override
public void run() {
for (int x = 0 ; x < 50 ; x ++) { // 获取50次的信息
System.out.println("【消费者】" + this.message.get());
}
}
}
public class YootkDemo { // 李兴华编程训练营:yootk.ke.qq.com
public static void main(String[] args) throws Exception {
Message message = new Message() ; // 实例化Message
new Thread(new ProducerThread(message)).start(); // 启动生产者线程
new Thread(new ConsumerThread(message)).start(); // 启动消费者线程
}
}
解决线程重复的操作问题
package com.yootk.demo;
class Message { // 描述一个公共空间
private String title ; // 描述信息的标题
private String content ; // 描述信息的内容
private boolean flag = true ; // 设置一个标志位(红绿灯控制)
// flag = true:表示可以生产,但是却无法进行消费(如果此时是由消费线程获取操作,则消费线程要等待)
// flag = false:表示可以消费,但是无法生产(如果此时是由生产线程获取操作,则生产线程要等待)
public synchronized void set(String title, String content) {
if (this.flag == false) { // 不允许生产,但是允许消费
try { // 此时的生产者线程暂停执行
super.wait(); // 等待消费者线程执行完毕后唤醒
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 如果执行了如下的代码则表示允许进行生产,但是生产的最后需要唤醒等待的消费线程
this.title = title ;
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.content = content ;
this.flag = false ; // 修改标志位,表示生产完成,可以消费
super.notify(); // 唤醒其他等待线程
}
public synchronized String get() {
if (this.flag == true) { // 不允许消费,只允许生产
try { // 此时的消费者线程暂停执行
super.wait(); // 等待消费者线程执行完毕后唤醒
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 如果执行了如下的代码则表示允许进行消费,但是消费的最后需要唤醒等待的生产线程
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.flag = true ; // 修改标志位,表示消费完成,可以生产
super.notify(); // 唤醒其他等待线程
return "title = " + this.title + "、content = " + this.content ;
}
}
class ProducerThread implements Runnable {
private Message message ; // 获取Message的引用
public ProducerThread(Message message) {
this.message = message ;
}
@Override
public void run() {
for (int x = 0 ; x < 50 ; x ++) { // 生产50次的信息
try {
if (x % 2 == 0) {
this.message.set("李兴华编程训练营", "yootk.ke.qq.com");
} else {
this.message.set("沐言科技", "www.yootk.com");
}
} catch (Exception e) {}
}
}
}
class ConsumerThread implements Runnable {
private Message message ; // 获取Message的引用
public ConsumerThread(Message message) {
this.message = message ;
}
@Override
public void run() {
for (int x = 0 ; x < 50 ; x ++) { // 获取50次的信息
System.out.println("【消费者】" + this.message.get());
}
}
}
public class YootkDemo { // 李兴华编程训练营:yootk.ke.qq.com
public static void main(String[] args) throws Exception {
Message message = new Message() ; // 实例化Message
new Thread(new ProducerThread(message)).start(); // 启动生产者线程
new Thread(new ConsumerThread(message)).start(); // 启动消费者线程
}
}
优雅的停止线程
package com.yootk.demo;
class Message implements Runnable {
private boolean stopFlag = false ; // 停止标记
@Override
public void run() {
for (int x = 0; x < 1000; x++) {
if (this.stopFlag) { // 如果内容为true,则退出循环
break; // 退出整个的循环
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("【Mesasge信息输出 - " + x + "】沐言科技:www.yootk.com");
}
}
public void stop() {
this.stopFlag = true ; // 修改停止标志
}
}
public class YootkDemo { // 李兴华编程训练营:yootk.ke.qq.com
public static void main(String[] args) throws Exception {
Message message = new Message() ; // 实例化Message
new Thread(message).start(); // 启动线程
Thread.sleep(2000); // 让线程先运行2秒的时间
message.stop();
}
}
守护线程
package com.yootk.demo;
class Message implements Runnable {
public Message() { // 构造方法
Thread daemonThread = new Thread(()->{
for (int x = 0 ; x < Integer.MAX_VALUE ; x ++) {
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("〖守护线程〗李兴华编程训练营:yootk.ke.qq.com");
}
}) ;
daemonThread.setDaemon(true); // 设置为守护线程
daemonThread.start(); // 守护线程启动
}
@Override
public void run() {
for (int x = 0; x < 10; x++) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("【Message信息输出】沐言科技:www.yootk.com");
}
}
}
public class YootkDemo { // 李兴华编程训练营:yootk.ke.qq.com
public static void main(String[] args) throws Exception {
Message message = new Message() ; // 实例化Message
new Thread(message).start(); // 启动线程
}
}
volatile
package com.yootk.demo;
class TicketThread implements Runnable {
private volatile int ticket = 3 ; // 一共卖3张票
@Override
public void run() {
while (this.sale()) {
;
}
}
public synchronized boolean sale() {
if (this.ticket > 0 ) { // 有票就卖
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("【" + Thread.currentThread().getName() + "】售票,剩余票数为,ticket = " + (--this.ticket));
return true ;
}
return false ;
}
}
public class YootkDemo { // 李兴华编程训练营:yootk.ke.qq.com
public static void main(String[] args) throws Exception {
TicketThread threadBody = new TicketThread() ;
new Thread(threadBody, "票贩子-A").start();
new Thread(threadBody, "票贩子-B").start();
new Thread(threadBody, "票贩子-C").start();
}
}
学习心得
在这个CPU单核性能发展出现瓶颈,CPU的发展越来越向多核发展的时代。
多线程的开发非常重要,最简单有较的提高程序的执行效率。可以有较的充分利用现在的硬件资源。