(黑马程序员)学习笔记,多线程(一)

本文介绍Java中创建和控制多线程的两种主要方法:继承Thread类和实现Runnable接口。同时,还探讨了如何利用同步锁(synchronized)确保线程间的正确交互,以及可能出现的死锁问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

什么是进程?每一个正在系统上运行的程序都是一个进程,是资源分配的基本单位,也是抢占处理机的调度单位。通常一个进程中包含一个或多个线程。

什么是线程?线程是程序中一个单一的顺序控制流程,与资源分配无关,它属于某一个进程,与进程内的其他线程共享进程的资源。


下面开始创建线程:

1.继承Thread类来创建线程

package thread;

public class ThreadTest1 {

	public static void main(String[] args) {
		Thread1 t1 = new Thread1("t1");
		Thread1 t2 = new Thread1("t2");
		
		t1.run();//只是调用run()方法,没有启动多线程
		t2.start();//开启多线程方法
		
		for(int i=0;i<60;i++){
			System.out.println("main..."+i);
		}
	}
}
//写线程就要继承线程类Thread,并重写run()方法
class Thread1 extends Thread{
	
	public Thread1(String name){
		super(name);
		System.out.println(Thread.currentThread().getName()+"创建完成");
	}
	//必须重写的方法,以实现自己在线程中的动作,用start()调用
	public void run(){
		for(int i=0;i<60;i++){
			System.out.println(this.getName()+"thread..."+i);
		}
	}
}

2.实现Runnable接口

package thread;

public class ThreadTest2 {
	public static void main(String[] args) {
		Thread2 t2 = new Thread2();//创建Runnable对象
		Thread t = new Thread(t2);//在创建线程时,加入Runnable对象
		
		t.start();//开启线程
		
		//为了区分Thread2线程,给主线程添加些内容
		for(int i=0;i<60;i++){
			System.out.println("main..."+i);
		}
	}
}

//线程也可以通过实现Runnable接口,重写run()方法
class Thread2 implements Runnable{

	//重写Run()方法,以实现自己在线程中的动作,用start()调用
	public void run(){
		for(int i=0;i<60;i++){
			System.out.println(Thread.currentThread().getName()+"thread..."+i);
		}
	}
}
这两种方式都可以成功创建线程,但还是推荐第二种方式,因为java是单继承的语言,也就是说一旦继承了Thread类,就无法在继承其他的类,这样不利于代码的灵活性。
多线程可以通过锁(synchronized)来控制让其交替运行:

package thread;
/**
 * 多线程交替运行,同步锁
 * @author asus
 *冻结线程wait(), 唤醒等待线程notify(), 唤醒所有等待线程notifyall()
 */
public class InputOutputDemo {

	public static void main(String[] args) {
		Ren r = new Ren();
		Input in = new Input(r);
		Output out = new Output(r);
		
		Thread t1 = new Thread(in);
		Thread t2 = new Thread(out);
		
		t1.start();
		t2.start();
	}
}
//封装对象
class Ren{
	String name = null;
	String sex = null;
	boolean flag = false;
}
//输入
class Input implements Runnable{
	private Ren r;
	//创建Input对象时获取共有资源
	Input(Ren r){
		this.r = r;
	}
	public void run(){

		int b = 0;
		//使用while循环不断地存入数据
		while(true){
			//同步锁,使存入和输出同步
			synchronized(r){
				//标志位,true表示完成存入数据,false表示完成输出数据
				if(r.flag){
					try {
						r.wait();//冻结线程
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				//根据b值的不同存入不同的数据
				if(b==0){
					r.name = "A";
					r.sex = "male";
				}else{
					r.name = "B";
					r.sex = "female";
				}
				
				b=(b+1)%2;
				r.flag = true;
				r.notify();//唤醒等待线程
			}

		}
	}
}

//输出
class Output implements Runnable{
	private Ren r;
	//创建Output对象时获取共有资源
	Output(Ren r){
		this.r = r;
	}
	public void run(){
		//使用while循环不断地存入数据
		while(true){
			//同步锁,使存入和输出同步
			synchronized(r){
				//标志位,true表示完成存入数据,false表示完成输出数据
				if(!r.flag){
					try {
						r.wait();//冻结线程
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				System.out.println(r.name+"..."+r.sex);
				r.flag = false;
				r.notify();//唤醒等待线程
			}
		}
	}
}
当然多个同步锁有时候也会造成死锁
package thread;

/**
 * 这是一个死锁程序:当线程中含有多个锁的时候,就有可能出现死锁现象,即每一个线程持有对方的锁且不被释放
 * @author asus
 *
 */
public class LockDemo {

	public static void main(String[] args) {
		
		//创建对象并传入标志位
		Lock l1 = new Lock(true);
		Lock l2 = new Lock(false);
		//创建线程
		Thread t1 = new Thread(l1);
		Thread t2 = new Thread(l2);
		//开启线程
		t1.start();
		t2.start();
	}
}

//提供锁对象
class MyLock{
	static Object lockA = new Object();
	static Object lockB = new Object();
}

//多线程死锁
class Lock implements Runnable {

	private boolean flag;

	Lock(boolean flag) {
		this.flag = flag;
	}
	
	//当两个或多个线程持有对方同步锁并且不释放,就会出现死锁现象
	public void run() {
		if(flag){
			//使用A锁同步
			synchronized(MyLock.lockA){
				System.out.println("if A");
				//使用B锁同步
				synchronized(MyLock.lockB){
					System.out.println("if B");
				}
			}
		}else{
			//使用B锁同步
			synchronized(MyLock.lockB){
				System.out.println("else A");
				//使用A锁同步
				synchronized(MyLock.lockA){
					System.out.println("else B");
				}
			}
		}
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值