线程学习总结及例子
- package com.hanchao.test;
- /**
- * 线程的创建方法一:继承java.lang.Thread类
- * @author hanlw
- * 2012 -07 -06
- */
- public class Thread1 extends Thread{
- @Override
- public void run() {
- //重写了Thread类的run()方法,该方法中是线程该做的事!
- System.out.println("线程的创建方法一:继承java.lang.Thread类;要重写run()方法。");
- }
- }
- package com.hanchao.test;
- /**
- * 线程的创建方法二:实现java.lang.Runnable接口
- * @author hanlw
- * 2012 -07 -06
- */
- public class Thread2 implements Runnable{
- public void run() {
- //实现Runnable接口的run()方法,该方法中写的是线程应该做的事!
- System.out.println("线程的创建方法二:实现java.lang.Runnable接口,并实现其run()方法");
- }
- }
- package com.hanchao.test;
- /**
- * 守护线程的测试类
- * @author hanlw
- * 2012- 07 -06
- */
- public class Thread3 extends Thread{
- @Override
- public void run() {
- while(true) {
- System.out.println("非守护线程");
- //线程睡上1000ms= 1s
- try {
- this.sleep(1000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- }
- package com.hanchao.test;
- /**
- * 线程同步问题的测试类
- * @author hanlw
- * 2012 -07 -06
- */
- public class Account {
- private float money = 2000f;
- public void getMoney(String name,float money) {
- if(money > this.money) {
- System.out.println("余额不足,当前余额为:"+this.money);
- } else {
- this.money -= money;
- System.out.println(name+"取款成功,当前余额为:"+this.money);
- }
- }
- }
- package com.hanchao.test;
- /**
- * 线程同步问题的测试类
- * @author hanlw
- * 2012 - 07 - 06
- */
- public class User extends Thread{
- private Account account;
- private String name;
- private float money;
- /**
- * 构造方法
- * @param account
- * @param name
- * @param money
- */
- public User(Account account,String name,float money) {
- this.account = account;
- this.name = name;
- this.money = money;
- }
- @Override
- public void run() {
- try {
- this.sleep(2000);//等待取款时间为2s
- account.getMoney(name, money);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- package com.hanchao.test;
- /**
- * 线程学习的测试类
- * @author hanlw
- *
- */
- public class Test_Six {
- public static void main(String[] args) throws Exception {
- /**
- * 线程的学习:
- *
- * 1.进程:同一时间片,单核只有一个进程运行。一个进程包括多个线程。
- *
- * 2.所谓的进程,本身不能执行,它只是一个资源的集合体,拥有地址空间,模块,内存。
- *
- * 线程是真正的执行单元,如果一个进程没有线程,那么就没有存在的意义,因为不可能执行。
- *
- * 3.线程的创建有两种方法:
- *
- * ① 继承java.lang.Thread类,并重写run()方法。
- * ② 实现java.lang.Runnable接口,并实现其run()方法。
- *
- */
- /**
- * 4.线程的启动(以前一直存在主线程main()方法)
- */
- //①,继承java.lang.Thread类的线程的启动
- /* Thread1 t1 = new Thread1();
- t1.start();
- //②实现java.lang.Runnable接口的线程的启动
- Thread t2 = new Thread(new Thread2());
- t2.start();
- */
- /**
- * 5.注意事项:
- *
- * ①继承Thread类后,无法再继承其他的类,但是实现Runnable接口后,还可以继承其他的类
- *
- * ②实现Runnable接口,访问当前线程需要使用Thread.currentThread()方法
- * eg.Thread.currentThread().getName();
- * Thread.currentThread().getId();
- *
- * ③继承Thread类,访问当前线程也可以使用this即可。
- * eg. this.currentThread()
- *
- *
- * 6.线程的生命周期:注意如下
- *
- * ①可以使用isAlive()方法判断线程是否死亡,该方法在线程处于就绪、运行、阻塞三种状态时返回true;
- * 处于新建及死亡状态时返回false;
- *
- * ②线程一旦死亡,则不能再次调用start()方法,让其重新执行。
- * (一个线程只能调用一次start()方法)
- *
- */
- /**
- * 7.join()线程:
- * Thread提供了让一个线程等待另一个线程完成的方法:join()。当某个程序在执行过程中调用了其他
- * 线程的join()方法,则当前线程被阻塞,直到被join()方法加入的线程完成为止。例子如下:
- */
- //join()线程的例子:
- /* for (int i = 0; i < 20; i++) {
- System.out.println("当前线程为:"+Thread.currentThread().getName()+"\t"+i);
- //当i为6时,我们加入Thread1线程
- if(i == 6) {
- Thread1 t11 = new Thread1();
- t11.start();
- t11.join();
- }
- }
- */
- /**
- * 8.守护线程:
- * 说明:除了特别设置外,我们创建的线程都是非守护线程。
- * 守护线程死亡了,守护线程也将死亡。
- *
- * 以前一直存在主线程main()
- */
- //例子:
- /* Thread3 t3 = new Thread3();
- t3.setDaemon(true);//设置守护线程。必须在start()前面啊!!!
- t3.start();
- for (int i = 0; i < 10; i++) {
- System.out.println(i);
- }
- */
- /**
- * 9.线程的同步问题:
- *
- * ①:要使用多线程编程?
- * 多线程就象是人体一样,一直在并行的做许多工作,例如,人可以同时呼吸,血液循环,消化食物的。
- * 多线程可以将一个程序划分成多个任务,他们彼此独立的工作,以方便有效的使用处理器和用户的时
- * 间.这种比喻精辟,只要我们的机器资源够用,就要尽量提高程序的执行速度,这样能让用户感到舒服。
- *
- * ②: 同步就是说多个任务之间是有先后关系的,一个任务需要等待另一个任务执行完毕才能继续执行。
- * 异步就是说多个任务之间没有先后关系,不需要相互等待各做各的事。
- *
- * ③:当多个对象同时对同一对象的实例变量进行操作时,会引起线程同步的问题。
- * 如下面的取款问题:模拟两个用户同时开始取款。
- * 当我们不停的执行时,我们会发现,有时候是tom取款成功,有时候是jack取款成功,有时候二者都可以取款成功
- * 显然这是不对的!!
- *
- *
- * 线程同步问题的避免方法:
- * <1>.要避免线程同步的问题,首先要避免实现全局的实例变量。
- * <2>.使用同步方法 ,如 public synchronized void ...
- * <3>.使用同步代码块, synchronized (this) {
- * 可能产生同步问题的程序
- * }
- * <4>.使用同步锁(JDK1.5以后才有的
- *
- * ④: 线程同步的方法:
- *
- * wait():使一个线程处于等待状态,并且释放所持有的对象的lock。
- *
- * sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,
- * 调用此方法要捕捉InterruptedException异常。
- *
- * notify():唤醒一个处于等待状态的线程,注意的是在调用此方法的时候,
- * 并不能确切的唤醒某一个等待状态的线程,而是由JVM确定唤醒哪个线程,
- * 而且不是按优先级。
- *
- * AnotityAll():唤醒所有处入等待状态的线程,注意并不是给所有唤醒线程一个对象的锁,
- * 而是让它们竞争。
- *
- *
- *
- */
- //模拟取款
- Account account = new Account();
- User user1 = new User(account, "tom", 1500);//tom取1500大洋
- User user2 = new User(account, "jack", 1500);//jack取1500大洋
- user1.start();
- user2.start();
- }
- }
1.同步方法:
- package com.hanchao.test;
- /**
- * 线程同步问题的测试类
- * @author hanlw
- * 2012 -07 -06
- */
- public class Account {
- private float money = 2000f;
- public synchronized void getMoney(String name,float money) {
- if(money > this.money) {
- System.out.println("余额不足,当前余额为:"+this.money);
- } else {
- this.money -= money;
- System.out.println(name+"取款成功,当前余额为:"+this.money);
- }
- }
- }
2.同步代码块
- package com.hanchao.test;
- /**
- * 线程同步问题的测试类
- * @author hanlw
- * 2012 -07 -06
- */
- public class Account {
- private float money = 2000f;
- public void getMoney(String name,float money) {
- synchronized (this) {
- if(money > this.money) {
- System.out.println("余额不足,当前余额为:"+this.money);
- } else {
- this.money -= money;
- System.out.println(name+"取款成功,当前余额为:"+this.money);
- }
- }
- }
- }
3.同步锁
- package com.hanchao.test;
- import java.util.concurrent.locks.ReentrantLock;
- /**
- * 线程同步问题的测试类
- * @author hanlw
- * 2012 -07 -06
- */
- public class Account {
- private float money = 2000f;
- private final ReentrantLock lock = new ReentrantLock();
- public void getMoney(String name,float money) {
- lock.lock();//枷锁
- try {
- if(money > this.money) {
- System.out.println("余额不足,当前余额为:"+this.money);
- } else {
- this.money -= money;
- System.out.println(name+"取款成功,当前余额为:"+this.money);
- }
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- lock.unlock();//解锁
- }
- }
- }
本文转自韩立伟 51CTO博客,原文链接:http://blog.51cto.com/hanchaohan/923199,如需转载请自行联系原作者