标签:
线程的创建两种实现 一种是继承 Thread 类(该类已实现 Runnable 接口) 一种是直接实现 Runnable 接口 Thread 类的定义如下: public class Thread extends Object implements Runnable { } 可发现 Thread 类实现了 Runnable 接口,所以直接继承 Thread 类即可, 并将 线程的程序代码 写在 run() 方法内,即可重写 Thread 类的 run() 方法 即可创建线程,多线程定义格式如下: [public] class 类名 extends Thread { 属性; 方法; public void run() // 重写 Thread 类的 run() 方法 { // 线程代码 } } Thread 类属于 java.lang 包,系统在运行时会自动导入,所以不需要使用 import 关键字显式导入 Thread 类 //以下用 Thread 类实现 public class Hi extends Thread { private String name; public Hi(){} public Hi(String name) { // Thread 类中的 run() 方法 setName(name); } public void run() { for (int i=0;i <=10 ;i++ ) { // 输出当前线程 System.out.println("当前运行的线程:"+getName()+", i="+i); } } public static void main(String[] args) { // 创建实例1 Hi t1 = new Hi("线程-1"); // 创建实例2 Hi t2 = new Hi("纯程-2"); // 启动线程1,2 t1.start(); t2.start(); } } // 其中的某此运行结果如下: 当前运行的线程:线程-1, i=0 当前运行的线程:纯程-2, i=0 当前运行的线程:线程-1, i=1 当前运行的线程:纯程-2, i=1 当前运行的线程:线程-1, i=2 当前运行的线程:纯程-2, i=2 当前运行的线程:线程-1, i=3 当前运行的线程:纯程-2, i=3 当前运行的线程:线程-1, i=4 当前运行的线程:纯程-2, i=4 当前运行的线程:线程-1, i=5 当前运行的线程:纯程-2, i=5 当前运行的线程:线程-1, i=6 当前运行的线程:纯程-2, i=6 当前运行的线程:纯程-2, i=7 当前运行的线程:纯程-2, i=8 当前运行的线程:纯程-2, i=9 当前运行的线程:纯程-2, i=10 当前运行的线程:线程-1, i=7 当前运行的线程:线程-1, i=8 当前运行的线程:线程-1, i=9 当前运行的线程:线程-1, i=10 /* 结果说明, 线程-1和线程-2是交替运行 也就是说程序是采用了多线程机制运行了 Hi继承了 Thread 类,因为 Thread 类中的 setName() 和 getName()方法是定义为 final类型的,运行 start()方法来调用 run() 方法 一个线程序对象只能调用一次 start(),多次则报错 */ // ================= 通过 Runnable 接口创建线程 Runnable 定义 public interface Runnable { public abstract void run(); } // 通过 Runnable 接口实现多线程 [public] class 类名 implements Runnable { 属性; 方法; public void run() { // 线程代码 } } // ========= public class Hi implements Runnable { private String name; public Hi() { } public Hi(String name) { setName(name); } public void setName(String name) { this.name = name; } public String getName() { return this.name; } public void run() { for(int i=0; i<5; i++) { System.out.println("当前运行的线程:"+getName()+", i="+i); } } public static void main(String[] args) { Hi r1 = new Hi("线程-1"); Hi r2 = new Hi("线程-2"); Thread t1 = new Thread(r1); Thread t2 = new Thread(r2); Thread t3 = new Thread(r1); t1.start(); t2.start(); t3.start(); } } /* 当前运行的线程:线程-1, i=0 当前运行的线程:线程-1, i=1 当前运行的线程:线程-1, i=2 当前运行的线程:线程-1, i=3 当前运行的线程:线程-1, i=4 当前运行的线程:线程-1, i=0 当前运行的线程:线程-1, i=1 当前运行的线程:线程-1, i=2 当前运行的线程:线程-1, i=3 当前运行的线程:线程-1, i=4 当前运行的线程:线程-2, i=0 当前运行的线程:线程-2, i=1 当前运行的线程:线程-2, i=2 当前运行的线程:线程-2, i=3 当前运行的线程:线程-2, i=4 */ // ============ // 在 Thread类中定义了一个类方法currentThread(), //可利用该方法获取主线程对象的引用 public class Hi implements Runnable { public void run() { for (int i=0;i<=10 ;i++ ) { System.out.println("当前运行的线程:"+Thread.currentThread()+", i="+i); } } public static void main(String[] args) { // 获取主线程 Thread mt = Thread.currentThread(); System.out.println("线程信息:"+mt); System.out.println("线程名称:"+mt.getName()); mt.setName("主线程"); System.out.println("线程名称:"+mt.getName()); Hi mThread = new Hi(); Thread t =new Thread(mThread); t.start(); mThread.run(); } } /* 线程信息:Thread[main,5,main] 线程名称:main 线程名称:主线程 当前运行的线程:Thread[主线程,5,main], i=0 当前运行的线程:Thread[主线程,5,main], i=1 当前运行的线程:Thread[主线程,5,main], i=2 当前运行的线程:Thread[主线程,5,main], i=3 当前运行的线程:Thread[主线程,5,main], i=4 当前运行的线程:Thread[主线程,5,main], i=5 当前运行的线程:Thread[主线程,5,main], i=6 当前运行的线程:Thread[主线程,5,main], i=7 当前运行的线程:Thread[主线程,5,main], i=8 当前运行的线程:Thread[主线程,5,main], i=9 当前运行的线程:Thread[主线程,5,main], i=10 当前运行的线程:Thread[Thread-0,5,main], i=0 当前运行的线程:Thread[Thread-0,5,main], i=1 当前运行的线程:Thread[Thread-0,5,main], i=2 当前运行的线程:Thread[Thread-0,5,main], i=3 当前运行的线程:Thread[Thread-0,5,main], i=4 当前运行的线程:Thread[Thread-0,5,main], i=5 当前运行的线程:Thread[Thread-0,5,main], i=6 当前运行的线程:Thread[Thread-0,5,main], i=7 当前运行的线程:Thread[Thread-0,5,main], i=8 当前运行的线程:Thread[Thread-0,5,main], i=9 当前运行的线程:Thread[Thread-0,5,main], i=10 */ // -------------- // 用 Thread 实现多线程 class Ticket extends Thread { private int ticket = 10; private String name; public Ticket(){} public Ticket(String name) { setName(name); } public void run() { while (ticket > 0) { if (ticket > 0) { System.out.println(Thread.currentThread().getName()+"卖出第"+(ticket--)+"张门票"); } } } } public class Hi { public static void main(String[] args) { Ticket window1 = new Ticket("第一窗口"); Ticket window2 = new Ticket("第二窗口"); window1.start(); window2.start(); } } /* 第一窗口卖出第10张门票 第二窗口卖出第10张门票 第一窗口卖出第9张门票 第二窗口卖出第9张门票 第一窗口卖出第8张门票 第二窗口卖出第8张门票 第二窗口卖出第7张门票 第二窗口卖出第6张门票 第二窗口卖出第5张门票 第二窗口卖出第4张门票 第二窗口卖出第3张门票 第二窗口卖出第2张门票 第二窗口卖出第1张门票 第一窗口卖出第7张门票 第一窗口卖出第6张门票 第一窗口卖出第5张门票 第一窗口卖出第4张门票 第一窗口卖出第3张门票 第一窗口卖出第2张门票 第一窗口卖出第1张门票 */ 实现了两个线程,但没有达到各自的共享目的 // ============= // 实现了共享 class Ticket implements Runnable { private int ticket = 10; public Ticket(){} public void run() { while(ticket > 0) { if (ticket > 0) { System.out.println(Thread.currentThread().getName()+"卖出第"+(ticket--)+"张门票..."); } } } } public class Hi { public static void main(String[] args) { Ticket window = new Ticket(); Thread t1 = new Thread(window,"第一窗口"); Thread t2 = new Thread(window,"第二窗口"); t1.start(); t2.start(); } } /* 第一窗口卖出第10张门票... 第一窗口卖出第8张门票... 第一窗口卖出第7张门票... 第一窗口卖出第6张门票... 第一窗口卖出第5张门票... 第一窗口卖出第4张门票... 第一窗口卖出第3张门票... 第一窗口卖出第2张门票... 第一窗口卖出第1张门票... 第二窗口卖出第9张门票... */ // ------------ // 获取并设置线程的名称 //如果在创建线程时,没有显式地为其设置名称,系统会自动地为其分配一个名称, // 一般格式为: Thread-n (n 表示从0 开始的整数) class ThreadDemo implements Runnable { public void run() { for (int i=0; i <= 5; i++) { System.out.println("当前运行线程:"+Thread.currentThread().getName()+",i="+i+"活动线程的数目:"+Thread.activeCount()); } } } public class Hi { public static void main(String[] args) { ThreadDemo tm = new ThreadDemo(); Thread t1 = new Thread(tm); Thread t2 = new Thread(tm,"线程-1"); Thread t3 = new Thread(tm); t3.setName("线程-2"); System.out.println("活动线程的数目:"+Thread.activeCount()); t1.start(); t2.start(); t3.start(); } } /* 活动线程的数目:1 当前运行线程:线程-2,i=0活动线程的数目:4 当前运行线程:线程-2,i=1活动线程的数目:4 当前运行线程:线程-2,i=2活动线程的数目:4 当前运行线程:线程-2,i=3活动线程的数目:4 当前运行线程:线程-2,i=4活动线程的数目:4 当前运行线程:线程-2,i=5活动线程的数目:4 当前运行线程:线程-1,i=0活动线程的数目:4 当前运行线程:线程-1,i=1活动线程的数目:3 当前运行线程:线程-1,i=2活动线程的数目:3 当前运行线程:线程-1,i=3活动线程的数目:3 当前运行线程:线程-1,i=4活动线程的数目:3 当前运行线程:线程-1,i=5活动线程的数目:3 当前运行线程:Thread-0,i=0活动线程的数目:4 当前运行线程:Thread-0,i=1活动线程的数目:2 当前运行线程:Thread-0,i=2活动线程的数目:2 当前运行线程:Thread-0,i=3活动线程的数目:2 当前运行线程:Thread-0,i=4活动线程的数目:2 当前运行线程:Thread-0,i=5活动线程的数目:2 */ // ================== // 线程的优先级 // 优先级从 1-10,默认为 5,用 setPriority()设置优先级 /* 优先级常量表示: public static final int MIN_PRIORITY 线程可以具有最低优先级 1 public static final int NORM_PRIORITY 线程的默认优先级 5 public static final int MAX_PRIORIRY 线程可以具有的最高优先级 10 */ class ThreadDemo implements Runnable { public void run() { for (int i=0; i<=5; i++) { System.out.println("当前运行线程:"+Thread.currentThread().getName()+", i="+i); } } } public class Hi { public static void main(String[] args) { ThreadDemo tm = new ThreadDemo(); Thread t1 = new Thread(tm, "线程-1"); Thread t2 = new Thread(tm, "线程-2"); Thread t3 = new Thread(tm,"线程-3"); Thread t4 = new Thread(tm,"线程-4"); t1.setPriority(Thread.MIN_PRIORITY); t2.setPriority(2); t3.setPriority(Thread.NORM_PRIORITY); t4.setPriority(Thread.MAX_PRIORITY); t1.start(); t2.start(); t3.start(); t4.start(); } } /* 当前运行线程:线程-4, i=0 当前运行线程:线程-4, i=1 当前运行线程:线程-4, i=2 当前运行线程:线程-4, i=3 当前运行线程:线程-4, i=4 当前运行线程:线程-4, i=5 当前运行线程:线程-2, i=0 当前运行线程:线程-2, i=1 当前运行线程:线程-2, i=2 当前运行线程:线程-3, i=0 当前运行线程:线程-3, i=1 当前运行线程:线程-3, i=2 当前运行线程:线程-3, i=3 当前运行线程:线程-3, i=4 当前运行线程:线程-3, i=5 当前运行线程:线程-1, i=0 当前运行线程:线程-1, i=1 当前运行线程:线程-1, i=2 当前运行线程:线程-1, i=3 当前运行线程:线程-1, i=4 当前运行线程:线程-1, i=5 当前运行线程:线程-2, i=3 当前运行线程:线程-2, i=4 当前运行线程:线程-2, i=5 */ // ------------------ // 让线程休眠 import java.util.Date; class ThreadDemo implements Runnable { public void run() { for (int i=0; i<=5; i++) { System.out.println("当前运行线程:"+Thread.currentThread().getName()+",i="+i+",时间:"+(new Date())); try { // 线程休眠 1s Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } } public class Hi { public static void main(String[] args) { // 创建线程实例 ThreadDemo tm = new ThreadDemo(); // 实例化 Thread 对象 t1,2,3,并设置线程名称 Thread t1 = new Thread(tm, "线程-1"); Thread t2 = new Thread(tm,"线程-2"); Thread t3 = new Thread(tm, "线程-3"); // 启动线程 t1.start(); t2.start(); t3.start(); } } // ================== // 线程的加入 import java.util.Date; class ThreadDemo implements Runnable { public void run() { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } for (int i=0; i<=5; i++) { System.out.println("当前运行的线程名:"+Thread.currentThread().getName()+",i="+i+",时间:"+(new Date())); } } } public class Hi { public static void main(String[] args) { ThreadDemo tm = new ThreadDemo(); Thread t1 = new Thread(tm, "线程-1"); Thread main = Thread.currentThread(); t1.start(); for (int i=0; i<=5; i++) { if(i==3) { try { t1.join(3000); } catch (Exception e) { e.printStackTrace(); } } System.out.println("main="+i+"-->"+new Date()); } } } /* main=0-->Mon Feb 23 17:06:06 CST 2015 main=1-->Mon Feb 23 17:06:06 CST 2015 main=2-->Mon Feb 23 17:06:06 CST 2015 当前运行的线程名:线程-1,i=0,时间:Mon F 当前运行的线程名:线程-1,i=1,时间:Mon F 当前运行的线程名:线程-1,i=2,时间:Mon F 当前运行的线程名:线程-1,i=3,时间:Mon F 当前运行的线程名:线程-1,i=4,时间:Mon F 当前运行的线程名:线程-1,i=5,时间:Mon F main=3-->Mon Feb 23 17:06:07 CST 2015 main=4-->Mon Feb 23 17:06:07 CST 2015 main=5-->Mon Feb 23 17:06:07 CST 2015 */ // ---------------- // 线程的唤醒 import java.util.Date; class ThreadDemo implements Runnable { public void run() { System.out.println("开始运行 run() 方法的时刻:"+(new Date())); try { Thread.sleep(5000); } catch (Exception e) { System.out.println("线程被唤醒"); } System.out.println("结束运行 run() 方法的时刻:"+(new Date())); } } public class Hi { public static void main(String[] args) { ThreadDemo tm = new ThreadDemo(); Thread t1 = new Thread(tm, "线程-1"); t1.start(); try { t1.sleep(2000); } catch (Exception e) { e.printStackTrace(); } t1.interrupt(); } } /* 开始运行 run() 方法的时刻:Mon Feb 23 17:32:46 CST 2015 线程被唤醒 结束运行 run() 方法的时刻:Mon Feb 23 17:32:48 CST 2015 */ // ================== // 后台线程 // setDaemon() 设置线程为后台线程 // isDaemon() 判断是否为后台线程 class ThreadDemo implements Runnable { public void run() { int i=0; while(true) { System.out.println("i="+i++); } } } public class Hi { public static void main(String[] args) { ThreadDemo tm = new ThreadDemo(); Thread t1 = new Thread(tm, "线程-1"); t1.setDaemon(true); if(t1.isDaemon()) { t1.start(); } } } // ------------ // 线程的礼让, yield()让出运行权 class ThreadDemo implements Runnable { public void run() { for (int i=0; i <= 10; i++) { System.out.println("当前运行的线程:"+Thread.currentThread().getName()+",i="+i); Thread.currentThread().yield(); } } } class ThreadDemo1 implements Runnable { public void run() { for (int i=0; i<=10; i++) { System.out.println("当前运行的线程:"+Thread.currentThread().getName()+",数字 i="+i); } } } public class Hi { public static void main(String[] args) { ThreadDemo tm1 = new ThreadDemo(); ThreadDemo1 tm2 = new ThreadDemo1(); Thread t1 = new Thread(tm1, "线程-1"); Thread t2 = new Thread(tm2, "线程-2"); t1.start(); t2.start(); } } // ================= class Ticket implements Runnable { private int ticket = 10; public Ticket() { } public void run() { while(ticket > 0) { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } if(ticket > 0) { System.out.println(Thread.currentThread().getName()+"卖出第"+(ticket--)+"张门票...."); } } } } public class Hi { public static void main(String[] args) { Ticket window = new Ticket(); Thread t1 = new Thread(window,"第一窗口"); Thread t2 = new Thread(window, "第二窗口"); t1.start(); t2.start(); } } /* 第一窗口卖出第10张门票.... 第二窗口卖出第10张门票.... 第一窗口卖出第9张门票.... 第二窗口卖出第8张门票.... 第一窗口卖出第7张门票.... 第二窗口卖出第6张门票.... 第一窗口卖出第5张门票.... 第二窗口卖出第4张门票.... 第一窗口卖出第3张门票.... 第二窗口卖出第2张门票.... 第一窗口卖出第1张门票.... */ // 发现有重票,所以实现同步有两种方法;同步代码码头,同步方法 // --------------- // 同步代码块 /* synchronized (object obj) { // code } */ class Ticket implements Runnable { private int ticket = 10; public Ticket(){} public void run() { while(ticket >=1) { synchronized(this) { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } if(ticket > 0) { System.out.println(Thread.currentThread().getName()+"卖出第"+(ticket--)+"张门票..."); } } } } } public class Hi { public static void main(String[] args) { Ticket window = new Ticket(); Thread t1 = new Thread(window, "第一窗口"); Thread t2 = new Thread(window, "第二窗口"); t1.start(); t2.start(); } } /* 第一窗口卖出第10张门票... 第一窗口卖出第9张门票... 第一窗口卖出第8张门票... 第一窗口卖出第7张门票... 第一窗口卖出第6张门票... 第一窗口卖出第5张门票... 第一窗口卖出第4张门票... 第一窗口卖出第3张门票... 第一窗口卖出第2张门票... 第一窗口卖出第1张门票... */ // ============== // 同步方法 /* [访问控制符] [static | final] synchronized 返回类型 方法名(参数列表) { // code } */ class Ticket implements Runnable { private int ticket = 10; public Ticket() { } public void run() { while(ticket > 0) { this.sale(); } } public synchronized void sale() { if(ticket > 0) { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"卖出第"+(ticket--)+"张门票..."); } } } public class Hi { public static void main(String[] args) { Ticket window = new Ticket(); Thread t1 = new Thread(window, "第一窗口"); Thread t2 = new Thread(window, "第二窗口"); t1.start(); t2.start(); } } // ================ /* 可以通过 java.util.concurrent.locks.ReentrantLock 类对象 调用 lock(),unlock() 来实现加锁与解锁方法 */ import java.util.concurrent.locks.*; class Ticket implements Runnable { private final ReentrantLock lock = new ReentrantLock(); private int ticket = 10; public Ticket() { } public void run() { while(ticket > 0) { lock.lock(); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } if(ticket > 0) { System.out.println(Thread.currentThread().getName()+"卖出第"+(ticket--)+"张门票..."); } lock.unlock(); } } } public class Hi { public static void main(String[] args) { Ticket window = new Ticket(); Thread t1 = new Thread(window, "第一窗口"); Thread t2 = new Thread(window, "第二窗口"); t1.start(); t2.start(); } } // ========== 线程的通信沟通 notify(), notifyAll(), wait() //唤醒等待池中的线程 public final void notify() // 唤醒等待池中所有的线程 public final void notifyAll() //使当前的线程等待 public final void wait() throws InterruptedException // 使当前的线程等待,并设置最长的时间,以毫秒为单位 public final void wait(long timeout) throws InterruptedException //使当前的线程等待时间,毫秒加纳秒 public final void wait(long timeout, int nanos) throws InterruptedException public class Food { private int number = 0; private String food = null; public Food(){} public Food(String Food, int number) { this.food = Food; this.number = number; } public synchronized void setfood(int n) { if(this.number != 0) { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } number = n; System.out.println("放置"+this.food+"第"+this.number+"批 次"); notify(); } public synchronized String getfood() { if(this.number == 0) { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("\t取走第"+this.number+"批次"+this.food); this.number = 0; notify(); return food+number; } public static void main(String[] args) { Food f = new Food("yes", 0); SetFood sf = new SetFood(f); GetFood gf = new GetFood(f); new Thread(sf).start(); new Thread(gf).start(); } } public class SetFood implements Runnable { private Food Food; public SetFood(Food Food) { this.Food = Food; } public void run() { for (int number = 1; number <= 5; number++) { try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } Food.setfood(number); } } } public class GetFood implements Runnable { private Food Food; public GetFood(Food Food) { this.Food = Food; } public void run() { for (int number = 1; number <= 5; number++) { try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } Food.getfood(); } } } // -----------------------
标签:
原文地址:http://www.cnblogs.com/lin3615/p/4302508.html