java学习笔记-----多线程
多线程
1.继承Thread类
Thread类是在java.lang包中定义的,一个类只要继承了Thread类,就成为多线程,而且必须覆写run方法,此方法为线程的主体。而如果要正确的启动线程,不能直接调用run()方法,而应该调用Thread类中继承过来的start方法
[使用格式]
class 类名称 extends Thread{
属性;
方法;
public void run(){
线程主体;
}
}
案例
package org.sz.demo07.threaddemo;
class MyThread extends Thread{
private String name;
public MyThread(String name) {
this.name =name;
}
public void run() {
for(int i = 0; i < 10; i++ ) {
System.out.println(name + "运行 , i =" + i);
}
}
}
public class ThreadDemo01{
public static void main(String args[]) {
MyThread mt1 = new MyThread("线程 a");
MyThread mt2 = new MyThread("线程 b");
mt1.start();
mt2.start();
}
}
因为哪个线程对象抢到了cpu资源,哪个线程就可以运行,所以每次运行的结果肯定是不一样的
2.Runnable接口
在java中也可以通过实现Runnable接口来实现多线程,Runnable接口中只定义了一个抽象方法;
public void run();
【使用格式】
class 类名称 implements Runnable{
属性;
方法;
public void fun(){
线程主体;
}
}
- 使用Runnable接口的优点
- 适合多个相同程序代码的线程去处理同一个资源;
- 可以避免由于单继承局限所带来的影响;
- 增加了程序的健壮性,代码能够被多个线程所分享,代码与数据是独立的人
案例:
class MyThread implements Runnable {
private String name;
public MyThread(String name) {
this.name = name;
}
public void run() {
for(int i =0; i < 10; i ++) {
System.out.println(name +"运行" +i);
}
}
};
public class RunnableDemo01{
public static void main(String args[]) {
MyThread mt1 = new MyThread("线程 a ");
MyThread mt2 = new MyThread("线程 b ");
Thread t1 = new Thread (mt1);
Thread t2 = new Thread (mt2);
t1.start();
t2.start();
}
}
*Thread 类是Runnable类的子类
- 如果一个类继承了Thread类,则不适合多个线程共享资源,而实现了Runnable接口,就可以利用 synchronized(this)方便地实现资源的共享;
- 案例 Thread不能资源共享
class MyThread extends Thread{
private int ticket = 5;
public void run() {
for(int i = 0; i < 100; i++ ) {
if(ticket>0) {
System.out.println("卖票: ticket = " + ticket--);
}
}
}
}
public class ThreadDemo02{
public static void main(String args[]) {
MyThread mt1 = new MyThread();
MyThread mt2 = new MyThread();
MyThread mt3 = new MyThread();
mt1.start();
mt2.start();
mt3.start();
}
}
- Runnable 接口 资源共享
class MyThread implements Runnable {
private int ticket = 5;
public void run() {
for(int i =0; i < 100; i ++) {
synchronized(this) { //设置需要同步的操作
if(ticket > 0) {
System.out.println("卖票:ticket =" +ticket --);
}
}
}
}
};
public class RunnableDemo02{
public static void main(String args[]) {
MyThread mt = new MyThread();
new Thread(mt).start();
new Thread(mt).start();
new Thread(mt).start();
}
}
3.同步方法
使用synchronized关键字将一个方法声明成同步方法
- 案例
class MyThread implements Runnable {
private int ticket = 5;
public synchronized void run() {
for(int i =0; i < 100; i ++) {
if(ticket > 0) {
System.out.println("卖票:ticket =" +ticket --);
}
}
}
};
public class RunnableDemo03{
public static void main(String args[]) {
MyThread mt = new MyThread();
new Thread(mt).start();
new Thread(mt).start();
new Thread(mt).start();
}
}
4.线程的状态
- 创建状态 :准备好了一个多线程的对象; Thread t = new Thread()
- 就绪状态:调用了start()方法,等待cpu进行调度
- 运行状态,执行run()方法
阻塞状态:暂时停止执行,可能将资源交给其他线程使用 - 终止状态:线程停止使用
- 实际上线程调用start方法时不是立刻启用,而是等待cpu进行调度;
5.线程操作的主要方法
a.取得线程名称
- 线程的名字在线程启动之前设置,避免重名
class MyThread implements Runnable {
public void run() {
for(int i = 0; i < 3; i++) {
System.out.println(Thread.currentThread().getName()+ "运行 ,i = " + i);
}
}
}
public class ThreadNameDemo{
public static void main(String args[]) {
MyThread mt = new MyThread();
new Thread(mt).start(); //系统自动设置线程名称
new Thread(mt,"线程——a").start(); // 手动设置线程名称
new Thread(mt,"线程——b").start(); // 手动设置线程名称
new Thread(mt).start();
new Thread(mt).start();
}
}
b.取得当前的线程名称
class MyThread implements Runnable {
public void run() {
for(int i = 0; i < 3; i++) {
System.out.println(Thread.currentThread().getName()+ "运行 ,i = " + i);
}
}
}
public class CurrentThreadDemo{
public static void main(String args[]) {
MyThread mt = new MyThread();
new Thread(mt,"线程").start(); // 启动线程
mt.run();
}
}
- 主方法也是一个线程
- 在java运行时至少启动了2个线程,启动时,会启动一个JVM,每个JVM实际上就是在操作系统中启动了一个进程,java中本身具备了垃圾收集机制
c.判断线程是否启动
class MyThread implements Runnable {
public void run() {
for(int i = 0; i < 3; i++) {
System.out.println(Thread.currentThread().getName()+ "运行 ,i = " + i);
}
}
}
public class ThreadAlivaDemo{
public static void main(String args[]) {
MyThread mt = new MyThread();
Thread t = new Thread(mt,"编程");
System.out.println("线程开始执行之后-->" + t.isAlive());
t.start();
System.out.println("线程开始执行之后-->" + t.isAlive());
for(int i = 0; i< 3; i++ )
{
System.out.println(" main 运行 -->" + i);
}
System.out.println("线程开始执行之后-->" + t.isAlive());
}
};
d.线程的强制运行
- 之后的输出全部由一个线程完成,主线程必须等待这个线程完成之后才会继续执行;使用join方法
class MyThread implements Runnable{
public void run() {
for(int i = 0; i < 50;i ++ ){
System.out.println(Thread.currentThread().getName() + "运行, i=" +i);
}
}
};
public class ThreadJoinDemo{
public static void main(String main[]) {
MyThread mt1 = new MyThread ();
Thread t = new Thread (mt1,"线程");
t.start();
for(int i = 0; i < 50; i++) {
if(i>10) {
try {
t.join();
}catch (InterruptedException e) {}
}
System.out.println("Main线程运行-->" + i);
}
System.out.println("代码运行之后-->" + t.isAlive());
}
}
e.线程的休眠
- 允许一个线程进行短暂的休眠,直接使用Thread.sleep()方法即可实现休眠
class MyThread implements Runnable{
public void run() {
for(int i = 0; i < 50;i ++ ){
try{
Thread.sleep(500);
}catch(Exception e) {}
System.out.println(Thread.currentThread().getName() + "运行, i=" +i);
}
}
};
public class ThreadSleepDemo{
public static void main(String main[]) {
MyThread mt1 = new MyThread ();
Thread t = new Thread (mt1,"线程");
t.start();
}
}
f.线程的中断
- 中断线程的休眠,使用interrupt()方法
class MyThread implements Runnable{
public void run() {
System.out.println("1.进入run()方法");
try{
Thread.sleep(10000);
System.out.println("2.完成休眠");
}catch(Exception e) {
System.out.println("3.休眠被中断");
return;
}
System.out.println("4.run()方法正常结束");
}
};
public class ThreadInterruptDemo{
public static void main(String main[]) {
MyThread mt1 = new MyThread ();
Thread t = new Thread (mt1,"线程");
t.start();
try{
Thread.sleep(2000);
}catch(Exception e) {
}
t.interrupt();
}
}
f.后台线程
- 只要前台有一个线程在运行,整个Java进程都不会消失,所以此时可以设置一个后台线程,即使java进程结束,后台线程依然会继续执行,通过setDeamon()方法实现;
class MyThread implements Runnable{
public void run() {
while(true) {
System.out.println(Thread.currentThread().getName() +"在运行 ");
}
}
};
public class ThreadSetDeamon{
public static void main(String main[]) {
MyThread mt1 = new MyThread ();
Thread t = new Thread (mt1,"线程");
t.start();
}
}
g.线程的优先级
- 使用 setPriority()方法
- 三个优先级
- MIN_PRIORITY,NORM_PRIORITY,MAX_PRIORITY
class MyThread implements Runnable{
public void run() {
for(int i = 0; i < 5;i ++ ){
try {
Thread.sleep(500);
}catch(Exception e) {};
System.out.println(Thread.currentThread().getName() + "运行, i=" +i);
}
}
};
public class ThreadPriorityDemo{
public static void main(String main[]) {
Thread t1 = new Thread(new MyThread(),"线程a");
Thread t2 = new Thread(new MyThread(),"线程b");
Thread t3 = new Thread(new MyThread(),"线程c");
t1.setPriority(Thread.MIN_PRIORITY);
t2.setPriority(Thread.NORM_PRIORITY);
t3.setPriority(Thread.MAX_PRIORITY);
t1.start();
t2.start();
t3.start();
}
}
- 主线程的优先级
public class MainPriorityDemo01{
public static void main(String args[]) {
System.out.println("主函数的优先级" + Thread.currentThread().getPriority());
System.out.println("MAX_PRIORITY = " + Thread.MAX_PRIORITY);
System.out.println("MIN_PRIORITY = " + Thread.MIN_PRIORITY);
System.out.println("NORM_PRIORITY = " + Thread.NORM_PRIORITY);
}
}
主线程的优先级相当于 NORM_PRIORITY
h.线程的礼让
- 使用yield()方法
class MyThread implements Runnable{
public void run() {
for(int i =0; i < 5 ; i ++) {
System.out.println(Thread.currentThread().getName()+ "运行 , i = " + i);
if( i == 3 ) {
System.out.println("线程礼让");
Thread.currentThread().yield();
}
}
}
};
public class ThreadYieldDemo01{
public static void main(String args[]) {
MyThread mt=new MyThread();
Thread t1 = new Thread(mt,"线程a");
Thread t2 = new Thread(mt,"线程b");
t1.start();
t2.start();
}
}
6.案例
- a.继承Thread类
class MyThread extends Thread{
private int time;
public MyThread(String name,int time) {
super(name);
this.time = time;
}
public void run() {
try {
Thread.sleep(this.time);
}catch(Exception e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+ "休眠" + this.time+"毫秒");
}
};
public class ThreadDemo03{
public static void main(String args[]) {
MyThread mt1=new MyThread("线程a",1000);
MyThread mt2=new MyThread("线程b",2000);
MyThread mt3=new MyThread("线程c",3000);
mt1.start();
mt2.start();
mt3.start();
}
}
- b.使用Runnable接口
class MyThread implements Runnable{
private int time;
private String name;
public MyThread(String name,int time) {
this.name = name;
this.time = time;
}
public void run() {
try {
Thread.sleep(this.time);
}catch(Exception e) {
e.printStackTrace();
}
System.out.println(this.name+ "休眠" + this.time+"毫秒");
}
};
public class ThreadDemo04{
public static void main(String args[]) {
MyThread mt1=new MyThread("线程a",1000); //此处已命名
MyThread mt2=new MyThread("线程b",2000);
MyThread mt3=new MyThread("线程c",3000);
new Thread(mt1).start();
new Thread(mt2).start();
new Thread(mt3).start();
}
}
7. 线程的生命周期
- suspend():暂时挂起线程
- resume();恢复挂起的线程
- stop();停止线程
- 因为上面的三个方法都会产生死锁,所以现在一般不适用
案例:线程中的停止方法
class MyThread implements Runnable{
private boolean flag = true;
public void run() {
int i = 0;
while(this.flag) {
System.out.println(Thread.currentThread().getName() + "i = " + (i ++));
}
}
public void stop(){
this.flag = false;
}
}
public class ThreadStopDemo01{
public static void main(String args[]) {
MyThread mt = new MyThread();
Thread t = new Thread(mt,“线程”);
t.start();
try {
Thread.sleep(20);
}catch(Exception e) {
e.printStackTrace();
}
mt.stop();
}
}
本文地址:https://blog.csdn.net/weixin_45739665/article/details/107351967