java--线程(多线程)

本文介绍了多线程编程的基础概念,如进程与线程的区别,如何通过继承Thread或实现Runnable创建线程,并重点讲解了Java中的锁和synchronized同步机制。实例演示了使用synchronized关键字和this作为锁的不同场景。此外,还提及了定时器和线程池在并发编程中的应用。

线程:多线程

进程:可以并行操作的。一个应用程序至少有一个进程
进程与进程之间的通讯,是通过系统级别,比较重量级的。每开一个进程,对操作系统来说,都是一个比较复杂和耗时的过程。

有一些程序需要并行执行,其原理是以空间换取时间。提高效率

一个进程可以有多个线程
至少有一个线程。创建和切换线程的开销要比进程小。

并行:物理真正多个cpu核心执行代码
并发:逻辑上多个线程。进程同时执行,时间片切换

使用多线程的两种方式:

1.继承Thread类,重写Run()方法。在run方法中编写业务逻辑。通过start方法启动。

package com.situ.chaoter1;

public class Test1 {

    public static void main(String[] args) {
	long start = System.currentTimeMillis();
	System.out.println(start);
//	for(int i =0;i<10000;i++) {
//	    System.out.println(i);
//	}
	//第一种创建线程
	Thread t1 = new MyThread(0,5000); 
	Thread t2 = new MyThread(5001,10000);
	  //启动线程 
	 t1.start(); t2.start();
	
//	long end = System.currentTimeMillis();
//	System.out.println(end);//花费时间数(毫秒)
	
	
    }

}
package com.situ.chaoter1;

public class MyThread extends Thread{

    private int from;
    private int to;
    public MyThread(int from, int to) {
	super();
	this.from = from;
	this.to = to;
    }
    
    @Override
    public void run() {
	for(int i =from;i<=to;i++) {
	    System.out.println(i);
	}
	System.out.println("------------------------");
 	System.out.println(System.currentTimeMillis());
    }
    
}

执行结果:
在这里插入图片描述

一个线程会执行到一定程度换换下一个线程执行,执行多长时间看系统分配的时间片大小。

2.实现Runable接口,然后Thread = new Thread(new Taskable(0,2500));新建一个对象并给它指定方法。

package com.situ.chaoter1;

public class Mytask implements Runnable {
    
    private int from;
    private int to;
    
    
    
    public Mytask(int from, int to) {
	super();
	this.from = from;
	this.to = to;
    }

    @Override
    public void run() {
	for(int i =from ;i<=to;i++) {
	    System.out.println(i);
	}
	System.out.println();
	System.out.println(System.currentTimeMillis());
    }

}

package com.situ.chaoter1;

public class Test2 {

    public static void main(String[] args) {
	
	System.out.println(System.currentTimeMillis());
	//第二种创建线程的方法,推荐使用
	Thread t1 = new Thread(new Mytask(0,2500));
	Thread t2 = new Thread(new Mytask(2500,5000));
	Thread t3 = new Thread(new Mytask(5000,7500));
	Thread t4 = new Thread(new Mytask(7500,10000));
	
	t1.start();
	t2.start();
	t3.start();
	t4.start();
	

    }

}

执行结果:
在这里插入图片描述

线程执行的结果通常是不可预料的。

线程出现问题,是由于多个线程在共享一个数据,如果线程不竞争数据,就不会出现问题。

同步和锁

:为了解决多线程并发访问资源的问题

在java中,锁是一个比较复杂的问题。

synchronized:重量级锁,可重入锁,但是线程的性能会下降,排它锁,性能弱,安全性最高

所有线程共用一把锁

两种用法:

1.synchronized(锁对象):同步块。同一时刻,只能有一个线程进入到同步块中。

package com.situ.chaoter3;

public class Test1 {
    public static void main(String[] args) {
	Task task = new Task();
	for(int i = 0;i<100;i++) {
	    Thread t = new Thread(task);
	    t.start();
	}
	System.out.println("分配任务成功,开始执行!");
    }
}

package com.situ.chaoter3;

public class Task implements Runnable{
    private static byte[] lock = new byte[0];
    
    public static int number = 0;
    
    public boolean doSomeThing() {
	synchronized (lock) {
	    number = ++number +1;
	    System.out.println(number);
	    if(number%2==1) {
		System.out.println("--------------------------");
		return true;
	    }
	    return false;
	}
    }

    @Override
    public void run() {
	while(true) {
	try {
	    Thread.sleep(10);
	} catch (InterruptedException e) {
	    
	    e.printStackTrace();
	}
	Thread.yield();
	
	    /*
	     * System.out.println(number); if(number%2==1) {
	     * System.out.println("--------------------------"); break; }
	     */
	
	//同步代码块
	boolean b = doSomeThing();
	if(b) {
	    break;
	}
    }
    
  }

}

2将synchronized定义在方法的前面,则是以this为锁。
只需要将自己创建的静态锁删除,synchronized (this){}即锁定的模块。

package com.situ.chaoter3;

public class Task implements Runnable{
    /* private static byte[] lock = new byte[0]; */
    
    public static int number = 0;
    
    public boolean doSomeThing() {
	synchronized (this) {
	    number = ++number +1;
	    System.out.println(number);
	    if(number%2==1) {
		System.out.println("--------------------------");
		return true;
	    }
	    return false;
	}
    }

    @Override
    public void run() {
	while(true) {
	try {
	    Thread.sleep(10);
	} catch (InterruptedException e) {
	    
	    e.printStackTrace();
	}
	Thread.yield();
	
	    /*
	     * System.out.println(number); if(number%2==1) {
	     * System.out.println("--------------------------"); break; }
	     */
	
	//同步代码块
	boolean b = doSomeThing();
	if(b) {
	    break;
	}
    }
    
  }

}

=======================================

其它解决方法

Timer: 定时器
Executors:工具类
ExecutorService:业务执行器

定时器:

package com.situ.chaoter4;

import java.util.Calendar;
import java.util.Timer;
import java.util.TimerTask;

public class Test1 {
public static void main(String[] args) {
    //定时器
    Timer timer = new Timer();
    //创建一个定时任务
    
    TimerTask tt = new MyTimerTask();
    
    Calendar can = Calendar.getInstance();
    can.set(Calendar.HOUR_OF_DAY,16);
    can.set(Calendar.MINUTE, 30);
    
    timer.schedule(tt, can.getTime());
    
    
}
}

package com.situ.chaoter4;

import java.util.TimerTask;

public class MyTimerTask extends TimerTask {

    @Override
    public void run() {
	System.out.println("时间到了!");
    }

}

在这里插入图片描述

线程、线程池

package com.situ.chaoter4;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Test2 {
    public static void main(String[] args) {
	//创建一个单线程
	ExecutorService es = Executors.newSingleThreadExecutor();
	es.submit(new MyTimerTask());
	
	//创建一个线程池
	ExecutorService  es1 = Executors.newCachedThreadPool();
	for(int i = 0 ;i<5;i++) {
	    es1.submit(new MyTimerTask());
	}
	System.out.println("任务分配完毕!");
    }
}

在这里插入图片描述

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

A little sea pig

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值