多线程

线程和进程之间的区别

1.进程是资源分配的最小单位,线程是cpu调度的最小单位,一个进程包含多个线程
2.线程不能看做独立应用,而进程可以看做独立应用
3.进程有独立的地址空间,相互不影响,线程只是进程中的不同执行路径
线程没有独立的地址空间

继承Thread

 public class MyThread extends Thread{
/*    
 * 利用继承中的特点     
 *   将线程名称传递  进行设置    
 */    
public MyThread(String name){    
super(name);        
}    
/*    
 * 重写run方法    
 *  定义线程要执行的代码    
 */    
public void run(){           
for (int i = 0; i < 20; i++) {                   
System.out.println(getName()+i);            
		}        
	}    
}
public class Demo {
    public static void main(String[] args) {
       System.out.println("这里是main线程");  
     MyThread mt = new MyThread("小强");            
     mt.start();//开启了一个新的线程    
     for (int i = 0; i < 20; i++) {    
System.out.println("旺财:"+i);            
		}        
	}    
}  

实现Runable接口

public class MyRunnable implements Runnable{
@Override    
public void run() {    
for (int i = 0; i < 20; i++) {        
System.out.println(Thread.currentThread().getName()+" "+i);            
		}        
	}    
}
public class Demo {
    public static void main(String[] args) {
        //创建自定义类对象  线程任务对象
        MyRunnable mr = new MyRunnable();
        //创建线程对象
        Thread t = new Thread(mr, "小强");
        t.start();
        for (int i = 0; i < 20; i++) {
            System.out.println("旺财 " + i);
        }
    }
}

Thread 和Runnable的区别

  1. 适合多个相同的程序代码的线程去共享同一个资源。
  2. 可以避免java中的单继承的局限性。
  3. 增加程序的健壮性,实现解耦操作,代码可以被多个线程共享,代码和线程独立。
  4. 线程池只能放入实现Runable或Callable类线程,不能直接放入继承Thread的类
  • 扩展.:java命令执行一个类的时候,实际上都会启动一个JVM,每一个JVM其实在就是在操作系统中启动了一个进

实现callable接口

ThreadLocal

在这里插入图片描述

同部代码块

 synchronized(同步锁){
     需要同步操作的代码
}

同部方法锁

public synchronized void method(){
   可能会产生线程安全问题的代码 
}

lock锁

  • java.util.concurrent.locks.Lock 机制提供了比synchronized代码块和synchronized方法更广泛的锁定操作,
    同步代码块/同步方法具有的功能Lock都有,除此之外更强大,更体现面向对象。
    Lock锁也称同步锁,加锁与释放锁方法化了,如下:
    Lock的子类ReentrantLock
    在这里插入图片描述
  • public void lock() :加同步锁。
  • public void unlock() :释放同步锁
public class Ticket implements Runnable{
private int ticket = 100;    
   
Lock lock = new ReentrantLock();    
/*    
 * 执行卖票操作    
 */    
	@Override    
	public void run() {    
//每个窗口卖票的操作         
//窗口 永远开启         
		while(true){        
		lock.lock();            
		if(ticket>0){//有票 可以卖            
	//出票操作                 
	//使用sleep模拟一下出票时间                 
		try {                
		Thread.sleep(50);                    
		} catch (InterruptedException e) {                                   
		e.printStackTrace();                    
}                
//获取当前线程对象的名字                 
	String name = Thread.currentThread().getName();                
	System.out.println(name+"正在卖:"+ticket‐‐);                
}   finally{     //无论程序是否发生异常都释放锁   
		lock.unlock();            
		}        
	}    
}

线程状态的概述

在这里插入图片描述

线程池

在这里插入图片描述

  ExecutorService executorService = Executors.newFixedThreadPool(2);
        executorService.submit(new runable());

线程池
newCachedThreadPool(通常是首选)
 创建一个可根据需要创建新线程的线程池,但是在以前构造的线程可用时将重用它们。对于执行很多短期异步任务的程序而言,这些线程池通常可提高程序性能。调用 execute 将重用以前构造
的线程(如果线程可用)。如果现有线程没有可用的,则创建一个新线程并添加到池中。终止并从缓存中移除那些已有 60 秒钟未被使用的线程。因此,长时间保持空闲的线程池不会使用任何资源。

newFixedThreadPool
  创建一个可重用固定线程数的线程池,一次性预先执行代价高昂的线程分配,限制线程的数量,这样可以节省时间,因为你不用为每个人物都固定的付出创建线程的开销

newSingleThreadExecutor
  Executor.ThreadExecutor()返回一个线程池(这个线程池只有一个线程),这个线程池可以在线程死后(或发生异常时)重新启动一个线程来替代原来的线程继续执行下去!

Java 里面线程池的顶级接口是 Executor,但是严格意义上讲 Executor 并不是一个线程池,而只是一个执行线程的工具。真正的线程池接口是 ExecutorService。

有返回值线程池
  实现Callable接口而不是Runnble接口,在java se5中引入的callable是一种具有参数的泛型,它的类型参数表示的是从方法call()中固定返回值,并且必须使用ExecutorService.submit()方法调用它
  (详情见java编程思想658页)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值