多线程
进程和线程
- 进程:执行中的程序
- 线程:程序执行中的单个顺序流程
- 多线程:一个进程中可以同时运行多个不同的线程
Thread类
- Thread类是具有多线程功能的类,实现了Runnable接口(一般作为父类派生子类)。
- Thread类的常用方法:
thread.run();//执行该线程的内容但未启动线程,相当于调用普通方法,一般派生子类时重写 thread.start();//启动该线程,调用run方法 thread.setName("纱雾");//更改该线程名称 thread.getName();//获取该线程名称 thread.currentTheard();//获取当前正在执行线程对象的引用 thread.setPriority(1);//更改该线程优先级,范围是1到10,默认为5 thread.getPriority();//获取该线程优先级 thread.sleep(100);//使当前正在执行线程暂停指定毫秒数 thread.yield();//暂停该线程 thread.activeCount();//返回当前线程组中活动线程个数 thread.isAlive();//返回该线程是否为启动状态 thread.getThreadGroup();//返回该线程所属线程组 thread.join();//等待该线程结束 thread.setDaemon(true);//将该线程设置为守护线程
多线程的实现方式
- 继承Thread类:
(1)创建子类继承Thread类
(2)重写子类run方法
(3)创建子类对象
(4)启动线程public class MyThread extends Thread {//定义子类继承Thraed类 public void run(){}//重写子类run方法 } MyThread my = new MyTread();//创建子类对象 my.start();//启动线程
- 实现Runnable接口:
(1)创建MyRunnable类实现Runnable接口
(2)重写MyRunnable类的run方法
(3)创建MyRunnable类的对象
(4)创建Thread类的对象,把MyRunnable类对象作为构造方法的参数
(5)启动线程public class MyRunnable implements Runnable {//创建MyRunnable类实现Runnable接口 public void run(){}//重写MyRunnable类的run方法 } MyRunnable my = new MyRunnable();//创建MyRunnable类的对象 Thread t = new Thread(my);//创建Thread类的对象,把MyRunnable类对象作为构造方法的参数 t.start();//启动线程
线程同步
-
synchronized:
为解决线程安全问题,Java引入监视器来保证共享数据操作的同步性。任何对象都可作为一个监视器,关键字synchronized修饰某个对象后,该对象就成为监视器。
synchronized有如下三种用法:
(1)synchronized 代码块:监视器就是指定的对象public class MyRunnable implements Runnable { private int flag = 10; private Object obj = new Object(); public void run() { while(true) { synchronized(obj) { if(flag > 0) { try { Thread.sleep(100); }catch(InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " " + flag); flag--; } } } } }
(2)synchronized 方法:监视器就是this对象
public class MyRunnable implements Runnable { private int flag = 10; private int t = 0; public void run() { while(true) { if(t % 2 == 0) { synchronized(this) { if(flag > 0) { try { Thread.sleep(100); }catch(InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " " + flag); flag--; } } }else { fun(); } t++; } } private synchronized void fun() { if(flag > 0) { try { Thread.sleep(100); }catch(InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " " + flag); flag--; } } }
(3)synchronized 静态方法:监视器就是相应的类
public class MyRunnable implements Runnable { private int flag = 10; private int t = 0; public void run() { while(true) { if(t % 2 == 0) { synchronized(MyRunnable.class) { if(flag > 0) { try { Thread.sleep(100); }catch(InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " " + flag); flag--; } } }else { fun(); } t++; } } private static synchronized void fun() { if(flag > 0) { try { Thread.sleep(100); }catch(InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " " + flag); flag--; } } }
-
线程安全类(类内部都是同步方法):
(1)StringBuffer:StringBuffer s1 = new StringBuffer(); StringBuilder s2 = new StringBuilder();
(2)Vector:
Vector<String> v = new Vector<String>; ArrayList<String> arr = new ArrayList<String>;
(3)Hashtable:
Hashtable<String,String> h1 = new Hashtable<String,String>; HashMap<String,String> h2 = new HashMap<String,String>;
(4)将线程不安全的集合类转化安全:
List<String> list = Collections.synchronizedList(new Arraylist<String>());
-
lock锁:
public class MyRunnable implements Runnable { private int flag = 10; private Lock lock = new ReetrantLock(); public void run() { while(true) { try { lock.lock(); if(flag > 0) { try { Thread.sleep(100); }catch(InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " " + flag); flag--; } }finally { lock.unlock(): } } } }
-
死锁问题:
如果多个线程都处于等待状态,彼此需要对方所占用的监视器所有权,就构成死锁,应尽量避免{ synchronized(A) { ... synchronized(B) { ... } } }