多线程
来源:互联网 发布:淘宝矜贵芳旗舰店 编辑:程序博客网 时间:2024/05/21 17:28
在编程中,多线程的意思是某个程序同时多个任务,这样的每一个任务则称为一个线程。线程这部分涉及的知识非常多,在实际开发的应用也是非常重要,这里将介绍基本的部分。
概念
线程:操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中实际运作单位。
进程:计算机中已运行程序的实体。进程本身不会运行,是线程的容器。
并行与并发:
* 并行:多个cpu实例或者多台机器同时执行一段处理逻辑,是真正的同时。
* 并发:通过cpu调度算法,让用户看上去同时执行,实际上从cpu操作层面不是真正的同时。[1]
实现多线程的几种基本方式
1、继承Thread类
public class Test02 extends Thread{ private String name; public Test02(String name) { this.name = name; } @Override public void run() { for(int i=0; i<100; i++){ System.out.println(name + i); } } public static void main(String[] args) throws InterruptedException { Test02 test1 = new Test02("one-->"); Test02 test2 = new Test02("two-->"); test1.start(); test2.start(); }}
2、实现Runnable接口
public class Test01 implements Runnable{ private String name; public Test01(String name){ this.name = name; } @Override public void run() { for(int i=0; i<100; i++){ System.out.println(name+"--->"+i); } } public static void main(String[] args) { Test01 test1 = new Test01("one"); Test01 test2 = new Test01("two"); Thread thread1 = new Thread(test1);//使用thread类执行start方法 Thread thread2 = new Thread(test2); thread1.start(); thread2.start(); }}
3、使用Callable和Future接口创建线程
public class Test03 implements Callable<Integer>{ @Override public Integer call() throws Exception { for(int i=0; i<100; i++){ System.out.println(Thread.currentThread().getName()+"--->"+i); } return null; } public static void main(String[] args) { Test03 t1 = new Test03(); Test03 t2 = new Test03(); FutureTask<Integer> task1 = new FutureTask<>(t1); FutureTask<Integer> task2 = new FutureTask<>(t2); new Thread(task1, "新建线程1").start(); new Thread(task2, "新建线程2").start(); }}
线程状态
使用getState()
方法可获取当前线程的状态(枚举类型),各种状态如下:
- New(新生)
当new一个新的线程时,线程还没开始运行时,状态是new
public class Test { public static void main(String[] args) { Thread thread = new Thread(); System.out.println(thread.getState()); }}
输出 NEW
- Runnable(可运行)
线程调用start执行时
public class Test { public static void main(String[] args) { Thread thread = new Thread(new Runnable() { public void run() { for(int i=0; i<100; i++){ System.out.println("i is "+i); } } }); thread.start(); System.out.println(thread.getState()); }}
输出 RUNNABLE
i is 0
i is 1
… i is 99
- Blocked(被阻塞)
当一个线程试图获取一个内部的对象锁(而不是java.util.concurrent库中的锁),而该锁被其他线程持有,则该线程进入阻塞状态。
public class Test { final Object lock = new Object(); class Example implements Runnable{ private String name; public Example(String name) { this.name = name; } @Override public void run() { //同步代码块 synchronized (lock) { for(int i=0; i<100; i++){ System.out.println(name+": i is "+i); } } } } public static void main(String[] args) { Example example1 = new Test().new Example("test1"); Example example2 = new Test().new Example("test2"); Thread thread1 = new Thread(example1); Thread thread2 = new Thread(example2); thread1.start(); thread2.start(); System.out.println(thread1.getState()); System.out.println(thread2.getState()); }}
输出 RUNNABLE
test1: i is 0
test2: i is 0
test1: i is 1
BLOCKED
test1: i is 2
…
- Waiting(等待)
等待状态,释放自身的锁进入Waiting状态并加入线程等待队列
public class Test { public synchronized void testMethod(){ try { this.wait(); System.out.println("waiting closed."); } catch (InterruptedException e) { e.printStackTrace(); } } public static void main(String[] args) throws InterruptedException { Thread thread1 = new Thread(new Runnable() { public void run() { new Test().testMethod(); } }); thread1.start(); Thread.sleep(10);//主线程休眠,转而去执行子进程 System.out.println(thread1.getState()); }}
输出 WAITING
waiting closed并不会输出
Timed waiting(计时等待)
在this.wait();
加上等待时间就会进入计时等待状态,例如this.wait(3000);
等待三秒输出内容TIMED_WAITING
waiting closed.
Terminated(被终止)
run方法执行结束线程终止
public class Test { public static void main(String[] args) throws InterruptedException { Thread thread = new Thread(new Runnable() { public void run() { System.out.println("run success"); } }); thread.start(); Thread.sleep(100); System.out.println(thread.getState()); }}
线程管理
sleep方法
static void sleep(long millis)
让当前正在运行的线程休眠一段时间
sleep是一个静态方法,不要用实例化的线程对象调用,其作用的是当前正在运行的线程。Thread.sleep(2000);
表示让当前线程休眠2秒,这里的2秒并不是准确的时间段,因为线程是由系统控制,实际时间可能大于2秒。yield方法
static void yield()
暂停当前正在执行的线程,重新进入就绪状态,这也是和sleep方法的区别的地方。如果有其他的可运行线程具有至少与此线程同样高的优先级,那么这些线程接下来会被调度。join方法
合并线程。等待终止指定的线程,让主线程等待子线程结束之后再执行
public class Test { public static void main(String[] args) throws InterruptedException { Thread thread1 = new Thread(new Runnable() { public void run() { for(int i=0; i<100; i++){ System.out.println("one--"+i); } } }); Thread thread2 = new Thread(new Runnable() { public void run() { thread1.start(); try { thread1.join(); } catch (InterruptedException e) { e.printStackTrace(); } for(int i=0; i<100; i++){ System.out.println("two--"+i); } } }); thread2.start(); }}
thread1在thread2中启动,为thread2子线程,调用join,等待thread1执行结束再执行thread2,相当于把两线程合并了。 void join(long millis)
join重载方法带参数,在指定时间段子线程未执行完将重新进入就绪状态,等待cpu调度。
- notify和notifyAll方法
notify方法只唤醒一个等待(对象的)线程并使该线程开始执行。所以如果有多个线程等待一个对象,这个方法只会唤醒其中一个线程,选择哪个线程取决于操作系统对多线程管理的实现。
notifyAll 会唤醒所有等待(对象的)线程。
public class Test { public synchronized void testMethod(){ try { System.out.println("thread start."); this.wait(); System.out.println("waiting closed."); } catch (InterruptedException e) { e.printStackTrace(); } } public synchronized void notifyMethod(){ this.notifyAll(); } public static void main(String[] args) throws InterruptedException { Test test = new Test(); Thread thread1 = new Thread(new Runnable() { public void run() { test.testMethod(); } }); Thread thread2 = new Thread(new Runnable() { public void run() { test.notifyMethod(); System.out.println("唤醒线程....."); } }); thread1.start(); Thread.sleep(1000); System.out.println(thread1.getState()); thread2.start(); }}
输出 thread start.
WAITING
唤醒线程.....
waiting closed.
interrupted和isInterrupted
Interrupted方法是一个静态方法,它检测当前的线程是否被中断。而且,调用interrupted方法会清除该线程的中断状态。
另一方面,isInterrupted方法是一个实例方法,可用来检验是否有线程被中断。调用这个方法不会改变中断状态。setPriority和getPriority
void setPriority(int newPriority)
设置线程的优先级。优先级必须在Thread.MIN_PRIORITY 与Thread.MAX_PRIORITY之
间。一般使用Thread.NORM_PRIORITY 优先级。final int getPriority()
获取线程的优先级结束线程
Tread中有stop方法,但改方法已经过时,不推荐使用。要结束线程,可设置标志来实现。
public class Test { class TestTread implements Runnable{ private boolean flag; private void stopThread() { this.flag=true; } @Override public void run() { for(int i=0; i<1000 && !flag; i++){ System.out.println("i is "+i); } } } public static void main(String[] args) throws InterruptedException { TestTread test = new Test().new TestTread(); Thread thread1 = new Thread(test); thread1.start(); Thread.sleep(3);//休眠延时 test.stopThread(); }}
输出一段i的值之后当执行stopThread方法线程就结束了。
- 多线程
- 多线程
- 多线程
- 多线程
- 多线程
- 多线程
- 多线程
- 多线程
- 多线程
- 多线程
- 多线程
- 多线程
- 多线程
- 多线程
- 多线程
- 多线程
- 多线程
- 多线程
- MySQL 请键入 NET HELPMSG 3534 以获得更多的帮助 的一种解决方案
- 求尾数
- 冒泡排序
- vsftpd 425 Security: Bad IP connecting.解决方法
- Android 性能优化——管理应用的内存
- 多线程
- hdu 2018
- Python的Twisted框架中reactor事件理解
- 标准库里的weak_ptr如何解决循环引用所带来的问题
- c#字典的一个错误使用
- Android事件分发02——Activity的dispatchTouchEvent验证一把
- 刷题总结#4
- 物联网相关
- 一次失败的在Ubuntu上安装Mysql的记录(请大神指点!)