学习多线程
提示:一起学习多线程呀,见谅啊,下面是是我的学习笔记
提示:仅供参考
前言
提示:太菜和自己有关,那就和我一起学习多线程
提示:以下是本篇文章正文内容,下面案例可供参考
一、线程与进程
进程:
是指一个内存中运行的应用程序,每个进程都有一个独立的内存空间
线程:
1.是进程中的一个执行路径,共享一个内存空间,线程之间可以自由切换,并发执行,一个进程最少有一个线程
2.线程实际上是在进程基础之上的进一步划分,一个进程启动之后,里面的若干执行路径可以划分成若干个线程。
二、同步与异步&并发与并行
同步:排队执行,效率低但是安全
异步:同时执行,效率高但数据不安全
并发:指两个或多个事件在同一个时间段内发生
并行:指两个或多个事件在同一时刻发生(同时发生)
三、继承Thread类
public class MyThread extends Thread{
@Override
public void run(){
for(int i=0;i<10;i++){
System.out.println(“锄禾日当午”+i);
}
}
}
ublic class Demo{
Public static void main(String[] args){
MyThread m = new MyThread();
M.start();
For(int i = 0;i<10;i++){
System.out.println(“汗滴禾下土”+i);
}
}
}
四、实现Runnable
public class MyRunnable implements Runnable{
@Override
public void run(){
for(int i=0;i<10;i++){
System.out.println(“锄禾日当午”+i);
}
}
}
public class Demo1{
public static void main(String[] args){
MyRunnable r = new MyRunnable();
Thread t = new Thread(r);
m.start();
for(int i = 0;i<10;i++){
System.out.println(“汗滴禾下土”+i);
}
}
}
}
实现Runnable与继承Thread相比有如下优势:
1.通过创建任务,然后给线程分配的方式来实现的多线程,更适合多个线程同时执行相同任务的情况
2.可以避免单继承所带来的局限性
3.任务与线程本身是分离的,提高了程序的健壮性
后续学习线程池技术
五、设置和获取线程名称
public class Demo2{
public static void main(String[] args){
System.out.println(Thread.currentThread().getName());
new Thread(new MyRunnable()).start();
new Thread(new MyRunnable()).start();
new Thread(new MyRunnable()).start();
}
}
}
static class MyRunnable implements Runnable{
@Override
public void run(){
for(int i=0;i<10;i++){
System.out.println(Thread.currentThread().getName());
}
}
}
六、线程安全问题
public static void main(String[] args){
Runnable run = new Ticket();
New Thread(run).start();
}
static class Ticket implements Runnable{
Private int count = 10;
@Override
public void run(){
while(count>0){
System.out.println(“正在准备买票”);
try{
Thread.sleep(1000);
}catch(InterruptedException e){
e.printStackTrace();
}
count--;
System.out.println(“出票成功,余票:”+count);
}
}
}
七、线程安全1-同步代码块
格式:synchronized(锁对象){
}
public static void main(String[] args){
Runnable run = new Ticket();
New Thread(run).start();
}
static class Ticket implements Runnable{
Private int count = 10;
//Private Object o =new Object();
@Override
public void run(){
Private Object o =new Object();
while(count>0){
Synchronized(0){
If(count>0){
System.out.println(“正在准备买票”);
try{
Thread.sleep(1000);
}catch(InterruptedException e){
e.printStackTrace();
}
count--;
System.out.println(Thread.currentThread().getName()+“出票成功,余票:”+count);
}
}
}
}
}
八、线程安全2-同步方法
public static void main(String[] args){
Runnable run = new Ticket();
New Thread(run).start();
}
static class Ticket implements Runnable{
private int count = 10;
//Private Object o =new Object();
@Override
public void run(){
private Object o =new Object();
while(count>0){
Synchronized(0){
boolean flag = sale();
If(!flag){
break;
}
}
public synchronized boolean sale(){
if(count>0){
System.out.println(“正在准备买票”);
try{
Thread.sleep(1000);
}catch(InterruptedException e){
e.printStackTrace();
}
count--;
System.out.println(Thread.currentThread().getName()+“出票成功,余票:”+count);
return true;
}
return false;
}
}
}
}
九、线程安全3-显示锁Lock
static class Ticket implements Runnable{
private int count = 10;
lock l= new ReentrantLock();
//Private Object o =new Object();
@Override
public void run(){
Private Object o =new Object();
while(true){
l.lock();
if(count>0){
System.out.println(“正在准备买票”);
try{
Thread.sleep(1000);
}catch(InterruptedException e){
e.printStackTrace();
}
count--;
System.out.println(Thread.currentThread().getName()+“出票成功,余票:”+count);
}
l.unlock();
}
}
}
十、线程死锁
public static void main(String[] args){
Culprit c = new Cuprit();
Police p = new Police();
New MyThread(c,p).start();
c.say(p);
}
static class MyThread extends Thread{
private Cuprit c;
private Police p;
public MyThread(Culprit c,Police p){
this.c = c;
this.p = p;
}
}
//罪犯
static class Culprit{
public void say(Police p){
System.out.println(“罪犯:你放了我,我放了人质”);
}
public void fun(){
System.out.println(“罪犯被放走了,罪犯也放了人质”);
}
}
//警察
static class Police{
public void say(Culprit c){
System.out.println(“警察:你放了人质,我放了你”);
c.fun();
}
public void fun(){
System.out.println(“警察救了人质,但是罪犯也跑了”);
}
}
十一、线程池概念
如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程
就会大大降低 系统的效率,因为频繁创建线程和销毁线程需要时间. 线程池就是一个容纳多个线程的容
器,池中的线程可以反复使用,省去了频繁创建线程对象的操作,节省了大量的时间和资源。
十二、缓存线程池
ExecutorService service = Executors.newCachedThreadPool();
//向线程池中 加入 新的任务
service.execute(new Runnable() {
@Override
public void run() {
System.out.println("线程的名称:"+Thread.currentThread().getName());
}
});
service.execute(new Runnable() {
@Override
public void run() {
System.out.println("线程的名称:"+Thread.currentThread().getName());
}
});
service.execute(new Runnable() {
@Override
public void run() {
System.out.println("线程的名称:"+Thread.currentThread().getName());
}
});
十三、定长线程池
ExecutorService service = Executors.newFixedThreadPool(2);
service.execute(new Runnable() {
@Override
public void run() {
System.out.println("线程的名称:"+Thread.currentThread().getName());
}
});
service.execute(new Runnable() {
@Override
public void run() {
System.out.println("线程的名称:"+Thread.currentThread().getName());
}
});
十四、单线程线程池
ExecutorService service = Executors.newSingleThreadExecutor();
service.execute(new Runnable() {
@Override
public void run() {
System.out.println("线程的名称:"+Thread.currentThread().getName());
}
});
service.execute(new Runnable() {
@Override
public void run() {
System.out.println("线程的名称:"+Thread.currentThread().getName());
}
});
十五、周期性任务定长线程池
ScheduledExecutorService service = Executors.newScheduledThreadPool(2);
/**
* 定时执行
* 参数1. runnable类型的任务
* 参数2. 时长数字
* 参数3. 时长数字的单位
*/
/*service.schedule(new Runnable() {
@Override
public void run() {
System.out.println("俩人相视一笑~ 嘿嘿嘿");
}
},5,TimeUnit.SECONDS);
*/
/**
* 周期执行
* 参数1. runnable类型的任务
* 参数2. 时长数字(延迟执行的时长)
* 参数3. 周期时长(每次执行的间隔时间)
* 参数4. 时长数字的单位
*/
service.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
System.out.println("俩人相视一笑~ 嘿嘿嘿");
}
},5,2,TimeUnit.SECONDS);