多线程
线程的创建
Thread类
- 自定义线程类继承Thread类
- 重写run()方法,编写线程执行体
- 创建线程对象,调用start()方法启动线程
public class Demo01 extends Thread{
public void run(){
// 重写线程进行内容
for (int i = 0; i < 20; i++) {
System.out.println("这是线程"+i);
}
}
// 主线程
public static void main(String[] args) {
Demo01 thread = new Demo01();
// 开始线程,与主线程同时进行,使用run()会先开启线程再进行主线程
thread.start();
for (int i = 0; i < 200; i++) {
System.out.println("主线程"+i);
}
}
}
Runnable接口
- 自定义线程类链接Runnable接口
- 重写run()方法,编写线程执行体
- 创建线程对象,在Thread方法中执行创建线程对象,调用start()方法启动线程
public class Demo01 implements Runnable{
public void run(){
// 重写线程进行内容
for (int i = 0; i < 20; i++) {
System.out.println("这是线程"+i);
}
}
// 主线程
public static void main(String[] args) {
Demo01 demo01 = new Demo01();
// 开始线程,与主线程同时进行
new Thread(demo01).start();
for (int i = 0; i < 200; i++) {
System.out.println("主线程"+i);
}
}
}
Lambda表达式
- 一个括号内用逗号分隔的形式参数,参数是函数式接口里面方法的参数
- 一个箭头符号:->
- 方法体,可以是表达式和代码块。
(parameters) -> expression 或者 (parameters) -> { statements; }
public class Demo1 {
public static void main(String[] args) {
runThreadByLambda();
runThreadByInnerClass();
}
public static void runThreadByLambda() {
/*
Runnable就是一个函数式接口:他只有一个方法run()方法。
1、因为run()方法没有参数,所以 ->前面的()中不需要声明形参
2、run返回的是void,所以不需要return。
3、->后面写的代码其实就是定义在run方法内的代码。因为此处代码只有一行,所以{}也可以省略。如果此处多与一行,则无法省略。
*/
Runnable runnable = () -> System.out.println("这个是用拉姆达实现的线程");
new Thread(runnable).start();
}
public static void runThreadByInnerClass() {
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println("这个是用内部类实现的线程");
}
};
new Thread(runnable).start();
}
}
线程的状态
- 线程的创建
- 线程的就绪
- 线程的运行
- 线程的阻塞
- 线程的死亡(死亡的线程不可二次启动)
可用state观测线程状态
public class Demo01{
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(()-> {
for (int i= 0;i< 5; i++) {
try {
Thread.sleep(1000);
}catch(InterruptedException e){
e.printStackTrace();
}
}
System.out.println("///////");
});
//观蔡状态
Thread.State state = thread.getState() ;
System.out.println(state); //NEW
//观蔡启动后
thread.start(); //后动线程
state = thread.getState();
System.out.println(state) ;//Run
while (state != Thread.State.TERMINATED){//只要线程不终止,就一直输出状态
Thread.sleep(100);
state = thread.getState(); //更新线程状态
System.out.println(state); //输出状态
}
}
}
线程的停止
public class Demo01 implements Runnable{
//建立一个表示
private boolean flag = true;
public void run(){
int i = 0;
while (flag){
System.out.println("run....Thread"+i++);
}
}
//重写一个stop
public void stop(){
this.flag = false;
}
// 主线程
public static void main(String[] args) {
Demo01 demo01 = new Demo01();
// 开始线程,与主线程同时进行
new Thread(demo01).start();
for (int i = 0; i < 200; i++) {
System.out.println("主线程"+i);
//设立停止位点
if (i == 100){
demo01.stop();
}
}
}
}
线程的休眠
- sleep方法,模拟网络延迟
线程的礼让
让当前执行的代码暂停,但不阻塞
public class Demo01{
public static void main(String[] args) {
myYield myyield = new myYield();
new Thread(myyield,"a").start();
new Thread(myyield,"b").start();
}
}
class myYield implements Runnable{
public void run(){
System.out.println(Thread.currentThread().getName()+"线程开始");
Thread.yield();//线程礼让,但礼让不一定成功
System.out.println(Thread.currentThread().getName()+"线程停止");
}
}
线程的强制执行
public class Demo01{
public static void main(String[] args) throws InterruptedException {
myYield myyield = new myYield();
Thread thread = new Thread(myyield);//静态代理
thread.start();
for (int i = 0; i < 1000; i++) {
System.out.println(i);
if (i == 200){
thread.join();//强制执行,线程执行完主线程才可继续执行
}
}
}
}
class myYield implements Runnable{
public void run(){
for (int i = 0; i < 100; i++) {
System.out.println("插队"+i);
}
}
}
线程的优先级
-
Java提供一个线程调度器来监控程序中启动后进入就绪状态的所有线程,线程调度器按照优先级决定应该调度哪个线程来执行。
-
线程的优先级用数字表示,范围从1~10.
- Thread.MIN_PRIORITY = 1;
- Thread.MAXPRIORITY = 10;
- Thread.NORM PRIORITY =5:
-
使用以下方式改变或获取优先级
- getPriority() . setPriority(int xxx)
-
优先级的设定建议在start()调度前
优先级低只是意味着获得调度的概率低.并不是优先级低就不会被调用了.这都是看CPU的调度
守护线程
- 线程分为用户线程和守护线程
- 虚拟机必须确保用户线程执行完毕
- 虚拟机不用等待守护线程执行完毕
- 如,后台记录操作日志,监控内存,垃圾回收等待...
public class Demo01{
public static void main(String[] args) {
God god = new God();
Yuo yuo = new Yuo();
Thread thread = new Thread(god);
thread.setDaemon(true);//开启守护线程
//启动上帝
thread.start();
//启动你
new Thread(yuo).start();
}
}
class Yuo implements Runnable{
public void run(){
for (int i = 0; i < 36500; i++) {
System.out.println("你开心的活着");
}
System.out.println("======goodbye world========");
}
}
class God implements Runnable{
public void run(){
while (true){
System.out.println("上帝保佑你");
}
}
}
线程同步
通过synchronized 关键字实现同步方法
同步块 : synchronized (obj){}
-
obj 称之为 同步监视器
- obj 可以是任何对象,但是推荐使用共享资源作为同步监视器
- 同步方法中无需指定同步监视器,因为同步方法的同步监视器就是this,就是这个对象本身,或者是 class
-
同步监视器的执行过程
-
第一个线程访问,锁定同步监视器,执行其中代码
-
第二个线程访问,发现同步监视器被锁定,无法访问
-
第一个线程访问完毕,解锁同步监视器
-
第二个线程访问,发现同步监视器没有锁,然后锁定并访问
-
线程池
- 背景:经常创建和销毁、使用量特别大的资源,比如并发情况下的线程,对性能影响很大。
- 思路:提前创建好多个线程,放入线程池中,使用时直接获取,使用完放回池中可以避免频繁创建销毁、实现重复利用。类似生活中的公共交通工具。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Demo01{
public static void main(String[] args) {
//1。创建服务,创建线程池
// newFixedThreadPool 参数为: 线程池大小
ExecutorService service = Executors.newFixedThreadPool(10);
//添加并执行线程
service.execute(new Yuo());
service.execute(new Yuo());
service.execute(new Yuo());
service.execute(new Yuo());
//2.关闭线程池
service.shutdown();
}
}
class Yuo implements Runnable{
public void run(){
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName() + i);
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("======END========");
}
}
标签:Thread,void,线程,println,new,多线程,public
From: https://www.cnblogs.com/zhao19811103/p/17233794.html