您好,欢迎访问一九零五行业门户网

Thread、线程创建的实例教程

主线程:执行主方法的线程,就叫做主线程
单线程程序:程序从mani开始从上到下依次运行
程序从main方法开始运行,jvm运行main方法,会找操作系统
 开辟一条通向cpu的执行路径,cpu可以通过这条路径来执行main方法
 这条路径有一个名字叫主(main)线程
创建线程方式一继承thread类
 实现步骤:
1.创建thread类的子类
2.重写thread类中的run方法,设置线程的任务
3.创建thread类的子类对象
4.调用thread类中的start方法开启一个新的线程,执行run方法
使该线程开始执行;java 虚拟机调用该线程的 run 方法。
结果是两个线程并发地运行;当前线程(main线程)和另一个线程(执行 run 方法的线程)。
多次启动一个线程是非法的。特别是当线程已经结束执行后,不能再重新启动。
打印的结果出现了随机性:
开启两个线程,对于cpu就选择权利
喜欢谁,就执行谁,所以就出现了随机性结果
 1 public class mythread extends thread{ 2     /* 3      * 2.重写thread类中的run方法,设置线程的任务 4      * 开启这个线程要干什么事情 5      */ 6     @override 7     public void run() { 8         for (int i = 0; i < 50; i++) { 9 system.out.println("run..."+i);10 }11 }12 }13 public static void main(string[] args) {14 //3.创建thread类的子类对象15 mythread mt = new mythread();16 //mt.run();//不会开启线程,还是单线程程序17 //4.调用thread类中的start方法开启一个新的线程,执行run方法18 mt.start();19 20 new mythread().start();21 22 for (int i = 0; i < 50; i++) {23 system.out.println("main..."+i);24 }25 }
线程的名称:
主线程:"main"
开启的其它线程的名称:"thread-0","thread-1"....
获取线程的名称
1.thread类中的方法getname
string getname() 返回该线程的名称。
2.thread类中的静态方法,获取当前正在执行的线程
static thread currentthread() 返回对当前正在执行的线程对象的引用。
设置线程的名称:
1.thread类中的方法setname(string name)
void setname(string name) 改变线程名称,使之与参数 name 相同。
2.子类添加带参构造,调用父类thread类的带参构造方法,传递线程的名称,让父类给线程起名字(让父亲给儿子起名字)
thread(string name) 分配新的 thread 对象。
创建线程方式—实现runnable接口
实现步骤:
1.创建runnable接口的实现类
2.重写runnable接口中的run方法,设置线程任务
3.创建runnable接口的实现类对象
4.创建thread类对象,构造方法中传入runnable接口的实现类
thread(runnable target) 分配新的 thread 对象。
5.调用thread类中的方法start,开启线程执行run方法
实现runnable的好处
1.避免了类继承thread类之后,无法继承其它的类(单继承的局限性)
2.把设置线程任务,和开启线程进行解耦,增强了扩展性
实现类的作用:就是设置线程任务
thread类的作用:开启线程
好处:传递不同的实现类,实现类重写的方法不一样,可以调用不同的方法
线程的匿名内部类使用
匿名:没有名字
内部类:写在其他类内部的类(成员位置:成员内部类,局部位置(方法中):局部内部类)
匿名内部类的格式:
new 父类/接口(){
重写父类/接口中的方法;
};
多线程的父类:
thread
runnable
1 new thread(){2 //重写run方法,设置线程任务3 @override4 public void run() {5 for (int i = 0; i < 20; i++) {6 system.out.println(thread.currentthread().getname()+":"+i);7 }8 }9 }
以上一堆代码就是一个创建子类重写父类方法的过程
相当于: new mythread().start();
程序出现了线程安全问题:卖了重复的票和不存在的票
解决方案:
第一种方式:可以使用同步代码块
synchronized(锁对象){
产生安全问题的代码;
访问了共享数据的代码;
}
注意:
必须要保证多个线程使用的是同一个锁对象
//在成员位置上创建一个锁对象(保证唯一)
1 object obj = new object(); 2 3 @override 4 public void run() { 5 //让卖票重复执行 6 while(true){ 7 8 * 同步代码块 9 * 程序会频繁的判断锁,获取锁,释放锁,所以会降低速度10 11 synchronized (obj) {12 if(ticket>0){13                     //为了提高安全问题的概率,让程序睡眠14                     try {15                         thread.sleep(10);16                     } catch (interruptedexception e) {17                         e.printstacktrace();18                     }19                     //卖票ticket--20                     system.out.println(thread.currentthread().getname()+...卖第+ticket--+张票);21                 }22             }23         }24     }
程序出现了线程安全问题:卖了重复的票和不存在的票
解决方案:
    第二种方式:同步方法
使用步骤:
    1.把可能出现安全问题的代码抽取到一个方法中
    2.把方法增加一个关键字synchronized
    修饰符 synchronized 返回值类型 方法名(参数){
    可能出现安全问题的代码;
    访问了共享数据的代码;
    }
同步方法使用的锁对象是什么?
   使用的就是本类对象new runnableimpl()-->叫this
静态的同步方法,使用时什么锁对象?
   使用的是本类对象的class属性(反射)
   runnableimpl.class
 1 *@override 2     public void run() { 3         //让卖票重复执行 4         while(true){ 5             payticket2(); 6         } 7     } 8      9     10      * 静态的同步方法11      12     public static synchronized void payticket2(){13         synchronized (runnableimpl.class) {14             if(ticket>0){15                 //为了提高安全问题的概率,让程序睡眠16                 try {17                     thread.sleep(10);18                 } catch (interruptedexception e) {19                     e.printstacktrace();20                 }21                 //卖票ticket--22                 system.out.println(thread.currentthread().getname()+...卖第+ticket--+张票);23             }24         }25     }26     27     28     29      * 抽取出一个同步方法30      * 快捷键:alt+shift+m31      32     public ynchronized void payticket1() {33         synchronized (this) {34             //system.out.println(this);//cn.itcsat.demo10.runnableimpl@6706435             if(ticket>0){36                 //为了提高安全问题的概率,让程序睡眠37                 try {38                     thread.sleep(10);39                 } catch (interruptedexception e) {40                     e.printstacktrace();41                 }42                 //卖票ticket--43                 system.out.println(thread.currentthread().getname()+...卖第+ticket--+张票);44             }45         }46     }
程序出现了线程安全问题:卖了重复的票和不存在的票
*
* 解决方案:
* 第三种方式:使用lock接口,jdk1.5之后出现的
*
* java.util.concurrent.locks.lock接口
* 方法:
* void lock() 获取锁。
* void unlock() 释放锁。  
*  接口的实现类:reentrantlock
*  
* 实现步骤:
* 1.在成员位置创建一个lock接口的实现类对象reentrantlock
* 2.在可能出现线程安全问题的代码前,调用lock方法获取锁
* 3.在可能出现线程安全问题的代码后,调用unlock方法释放锁
*
*1.在成员位置创建一个lock接口的实现类对象reentrantlock
lock l = new reentrantlock();
 1 @override 2     public void run() { 3         //让卖票重复执行 4         while(true){ 5             //2.在可能出现线程安全问题的代码前,调用lock方法获取锁 6             l.lock(); 7                 if(ticket>0){ 8                     //为了提高安全问题的概率,让程序睡眠 9                     try {10                         thread.sleep(10);11                         //卖票ticket--12                         system.out.println(thread.currentthread().getname()+...卖第+ticket--+张票);13                     } catch (interruptedexception e) {14                         e.printstacktrace();15                     }finally {16                         //3.在可能出现线程安全问题的代码后,调用unlock方法释放锁17                         l.unlock();     18                     }19                 }20         }
以上就是thread、线程创建的实例教程的详细内容。
其它类似信息

推荐信息