线程的使用方法:
public static void main(String[] args) { Runnable r = ()->{ while (true) { System.out.println("this is thread"); } }; Thread t = new Thread(r); t.start(); while (true) { System.out.println("this is main"); } }
步骤:实现Runnable接口的run方法,创建一个线程,执行start方法。不要调用run方法,这个方法只会执行一个线程中的任务,不会创建新线程。
2.中断线程
Runnable r = ()->{ int i=0; while(!Thread.currentThread().isInterrupted()) { //判断当前线程是否被终止 System.out.println("this is thread"); i++; if (i==100){ Thread.currentThread().interrupt(); //获取当前线程并向其发送中断请求,线程的中断状态将被设置为true } } };
3.线程状态
1)join()等待终止指定的线程
2)getState()得到这一线程的状态
4.线程属性
1)每个线程都有一个优先级,默认情况下一个线程继承它的父线程的优先级。
2)优先级最低为1,最高为10,默认为5,可以通过thread.setPriority()来设置优先级。
3)thread.setDaemon(true)将线程转换为守护进程,当只剩下守护进程时,虚拟机就退出了。守护进程应该永远不去访问固有资源,如文件、数据库等。
4)run方法不能抛出任何受查异常,但是非受查异常会导致进程终止。线程死亡时,异常被传到一个用于未捕获异常的处理器。
5.同步
1)锁对象:解锁语句必须放在finally中,而且不能使用带资源的try语句。
private int Acount=10000; public Lock lock = new ReentrantLock(); public void addcount(){ lock.lock(); try { Acount += 1000; System.out.println(meg+"加 Account is :"+Acount); } finally { lock.unlock(); } }
2)条件对象(条件变量)
一个锁可以有一个或者多个相关的条件对象,newCondition方法获取一个条件对象,调用await()方法使当前线程被阻塞,并放弃锁,将该线程放到条件的等待集中。对于await()的调用应该在while循环里,这样另外一个线程就能进来了。
signalAll()解除了该条件的等待集中的所有线程的阻塞状态。
3)synchronized
java中每个对象都有一个内部锁,并且该锁有一个内部条件,如果一个方法用synchronized声明,那么对象的锁将保护整个方法。使用wait、notifyAll、notify。
将静态方法声明为synchronized也是合法的,该方法会获得相关类的内部锁,没有其他线程可以调用同一个类的这个或任何其他的同步静态方法。
4)锁
tryLock() 尝试获得锁而不会发生阻塞,如果成功则返回真。
ReentrantReadWriteLock rwl = new ReentrantReadWriteLock() 构造一个读写锁对象
Lock readlock = rwl.readLock() 获取读锁
Lock writeLock = rwl.writeLock(); 获取写锁
6.执行器
如果程序中创建大量的生命期很短的线程,应该使用线程池,一个线程池包含了许多准备运行的空闲线程,将Runnable对象交给线程池,就会有一个线程调用run方法,当run方法退出时,线程不会死亡,而是在池中准备为下一个请求提供服务。
执行器(Executor)类有许多静态工厂方法来构建线程池。
ExecutorService pool = Executors.newCachedThreadPool();//返回带缓存的线程池 ExecutorService pool = Executors.newFixedThreadPool(10);//指定线程数 ExecutorService pool = Executors.newSingleThreadExecutor();//单个线程依次执行 Task task = new Task(1,pool); Future<?> res = pool.submit(task); //执行任务 pool.shutdown(); //关闭服务