多线程基础解析

文章介绍了线程的基本概念,包括线程在程序执行中的作用,以及多线程在实际应用中的例子如红蜘蛛、迅雷和QQ。接着,文章阐述了并行和并发的区别,并详细讲解了Java中实现多线程的两种方法:继承Thread类和实现Runnable接口,以及它们的优缺点。此外,还提到了线程的管理,如线程休眠、守护线程、线程同步、线程安全问题和死锁等概念。
摘要由CSDN通过智能技术生成

多线程

什么是线程?

        线程是程序执行的,一条路径,一个进程包含多想工作。

多线程应用场景

红蜘蛛,同时共享屏幕给多台电脑。

迅雷,开启多条线程一起下载。

qq。可以同时和多个人一起视频

多线程并行和并发的区别

并行:就是两个任务同时运行,甲任务进行的同时,乙任务也在进行(需要多核cpu)

并发:两个任务都在请求运行,而处理器只能接受一个任务,就把两个任务安排轮流进行,由于时间建个短,使人感觉两个任务都在进行。

java程序运行原理和jvm虚拟机的启动是单线程

多线程实现方法一

继承Thread类

1.定义类基础Thread

2.重写run方法

3.把想让线程感到活写在run方法中。

4.创建线程对象。

5.开启线程,内部会自动执行run方法(Start())。

public class Demo extends Thread{
	@Override
	public void run() {
		for (int i = 0; i < 1000; i++) {
			System.out.println("aa=====================");
		}
	}
		
	}


public class Demo1 {

	public static void main(String[] args) {
		Demo d=new Demo();
		//开启线程的方法
		d.start();
		for (int i = 0; i < 1000; i++) {
			System.out.println("bb");
		}
	}

}

多线程实现方法二

实现Runnable接口

1.定义类实现Runnable接口

2.重写run方法

3.把要做到事情放到run方法中

4.创建自定义的Runnable子类对象

5.创建Thread对象,传入Runnable

6.调用start方法,开启线程


public class Demo2 implements Runnable{

	@Override
	public void run() {
		for (int i = 0; i < 300; i++) {
			System.out.println("===============");
		}
		
	}

}


public class Demo3 {
	public static void main(String[] args) {
		Demo2 d=new Demo2();
	Thread t=new Thread(d);
	t.start();
	for (int i = 0; i < 300; i++) {
		System.out.println("-------------");
	}
	}
	
}

两种方法的区别*

a:继承Thread:由于子类重写了Thread类的run()方法,当调用start()是,直接找子类的run方法。

b:实现Runnable接口:构造函数中传入Runnable的引用成员遍历记住了它,start调用run方法时,内部判断成员遍历Runnable的引用是否为空,不为空编译的时候看的Runnable的run,运行时执行的是子类run方法。

继承Thread

好处:可以直接使用Thread类中的方法,代码简单。

弊端:如果已经有父类,就不能用这种方法(尽量不用)

实现Runnable接口

好处:即使自定义的线程已经有了父类也没关系,原因接口可以多实现。

弊端:不能直接使用Thread中的方法start,如果要使用先获取到线程对象,然后才能得到Thread的方法,代码复杂(推荐使用)

获取名字和设置名字

1.获取名字

通过getName方法获取线程对象的名称。

2.设置名称

1.通过构造函数传入String类型的名称

2.通过set函数。

public class Demo4 {
	public static void main(String[] args) {
	//初始化赋值改名
		new Thread("线程一") {
		@Override
		public void run() {
			System.out.println(this.getName()+"aaaa");
		}
	}.start();
	Thread t1=new Thread() {
		public void run() {
			//set修改,改名
			//this.setName("线程二");
			System.out.println(this.getName()+"bbbb");
			
			
		};
		
		
	};
	//方法二升级set改名
	t1.setName("线程三");
	t1.start();
	
	
	
	
	
	}
	
}

线程休眠

换算比:1秒=1000毫秒=1000X1000X1000纳秒

不表明需求,默认为纳秒,windos不支持会报错。

如果创建两个线程,写入休眠,不会让出cpu。

public static void main(String[] args) throws InterruptedException {
		for (int i = 20; i >0; i--) {
			Thread.sleep(1000);;//1000毫秒等于1秒
			System.out.println("倒计时"+i+"秒");
		}

	}

守护线程

cpu运行惯性会使守护线程多运行几次才会结束

加入线程(join())

        当前线程暂停,等待指定的线程执行结束后,当前线程在继续执行。

        join(参数,代表的是时间int类)可以等待指定的毫秒之后在继续运行。

	public static void main(String[] args) throws InterruptedException {
		Thread t1=new Thread("a") {
			@Override
			public void run() {
				for (int i = 0; i < 10; i++) {
				
					System.out.println(getName()+"=========");
				}
				
			}
		};
		
		Thread t2=new Thread("b") {
			@Override
			public void run() {
				for (int i = 0; i < 10; i++) {
					if(i==2) {
						try {
							t1.join(1);
						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}
					System.out.println(getName()+"xxxxxxx");
				}
				
			}
		};
		t1.start();
		t2.start();
	}

礼让线程(不明显,了解)

Thread.yield();//让出cpu

设置线程优先级

setPriority();


	public static void main(String[] args) throws InterruptedException {
		Thread t1=new Thread("a") {
			@Override
			public void run() {
				for (int i = 0; i < 100; i++) {
				
					System.out.println(getName()+"=========");
				}
				
			}
		};
		
		Thread t2=new Thread("b") {
			@Override
			public void run() {
				for (int i = 0; i < 100; i++) {
					
					System.out.println(getName()+"xxxxxxx");
				}
				
			}
		};
		t1.setPriority(Thread.MIN_PRIORITY);
		t2.setPriority(Thread.MAX_PRIORITY);
		t1.start();
		t2.start();
	}

}

同步代码块

使用sgnchronized关键字加上一个锁对象来定义一段代码,这就叫同步代码块。

锁芯可以是任意对象,同步代码块可以保证数据的完整性。

	@Override
		public void run() {
		while(true) {
			synchronized (Demo1.class) {
				if(ticet<=0) {
					break;
				}
//				try {
//					Thread.sleep(10);
//				} catch (InterruptedException e) {
//					// TODO Auto-generated catch block
//					e.printStackTrace();
//				}
			}
			System.out.println(getName()+"----第"+ticet--+"张票");
		}
		}
		public static void main(String[] args) {
			new Demo1().start();
			new Demo1().start();
			new Demo1().start();
			new Demo1().start();
		}

线程安全问题

多线程并发操作同一次数据,就可能出现线程安全。

使用同步技术可以解决这个问题,把操作数据的代码进行同步,不要多个线程一起操作。

public class Demo2  implements Runnable{
		private  int ticet=100;
		@Override
		public void run() {
		while(true) {
			synchronized (Demo2.class) {
				if(ticet<=0) {
					break;
				}
				try {
					Thread.sleep(10);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			System.out.println(Thread.currentThread().getName()+"----第"+ticet--+"张票");
			}
		}
		public static void main(String[] args) {
				Demo2 d=new Demo2();
				new Thread(d).start();;
				new Thread(d).start();;
				new Thread(d).start();;
				new Thread(d).start();;
		
		}
}

死锁

多线程同步的时候,如果同步代码镶嵌,使用的锁芯相同,就可能会出现死锁。

总结:开发的时候涉及到锁,切记不要区嵌套。

public class Demo1{
	private static String s1="左筷子";
	private static String s2="右筷子";

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		new Thread() {
			@Override
			public void run() {
				while(true) {
					synchronized (s1) {
					System.out.println(getName()+"    "+s1);	
					
					synchronized (s2) {
						System.out.println(getName()+"    "+s2);	
						}
				}
}
			}
		}.start();
		new Thread() {
			@Override
			public void run() {
				while(true) {
					synchronized (s2) 
					{
						
					System.out.println(getName()+"    "+s2);	
					
					synchronized (s1) {
					
						System.out.println(getName()+"    "+s1);	
						}
				}
}
			}
		}.start();
	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值