Java多线程技能
关键技术点:
线程的启动
如何使线程暂停
如何使线程停止
线程的优先级
线程安全相关问题
线程
线程可以理解成是在进程中独立运行的子任务
使用多线程技术后,可以在同一时间内运行更多不同种类的任务
继承Thread
继承Thread和实现Runnable接口两种创建线程的方式在工作时的性质是一样的,没有本质的区别
在使用多线程技术时,代码的运行结果与代码执行顺序或调用顺序是无关的(线程执行具有异步性)
thread.start()使线程得到运行,具有异步执行的效果
package multilThread.chapter1;
/**线程随机性
* 线程启动顺序与start()执行顺序无关
*/
public class Page6 extends Thread {
@Override
public void run(){
for(int i=0;i<10;i++){
try {
int time = (int)(Math.random()*1000);
Thread.sleep(time);
System.out.println("run="+Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
Page6 p = new Page6();
p.setName("myThread");
p.start();
for(int i=0;i<10;i++){
try {
int time = (int)(Math.random()*1000);
Thread.sleep(time);
System.out.println("main="+Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
运行结果:
实现Runnable
解决Java中不能多继承的问题
构造方法Thread(Runnable target)不但可以传入Runnable接口的对象,还可以传入一个Thead类的对象,这样做完全可以将一个Thread对象中的run()方法交由其他的线程进行调用。
package multilThread.chapter1;
/** 实现runnable接口
*/
public class Page8 implements Runnable {
@Override
public void run() {
System.out.println("运行中");
}
public static void main(String[] args) {
Page8 p = new Page8();
Thread t = new Thread(p);
t.start();
System.out.println("运行结束");
}
}
运行结果:
实例变量与线程安全
不共享数据:
/** 不共享数据
*/
public class Page9 extends Thread {
private int count = 5;
public Page9(String name){
super();
this.setName(name);
}
@Override
public void run(){
super.run();
while(count>0){
count--;
System.out.println("由"+this.currentThread().getName()+"计算,count="+count);
}
}
public static void main(String[] args) {
Page9 a = new Page9("A");
Page9 b = new Page9("B");
Page9 c = new Page9("C");
a.start();
b.start();
c.start();
}
}
运行结果:
共享数据:
/** 共享数据
*/
public class Page11 extends Thread {
private int count = 5;
@Override
synchronized public void run(){
super.run();
count--; //非原子操作
System.out.println("由"+this.currentThread().getName()+"计算,count="+count);
}
public static void main(String[] args) {
Page11 p = new Page11();
Thread a = new Thread(p,"A");
Thread b = new Thread(p,"B");
Thread c = new Thread(p,"C");
Thread d = new Thread(p,"D");
Thread e = new Thread(p,"E");
a.start();
b.start();
c.start();
d.start();
e.start();
}
}
运行结果:
在某些JVM中,i--操作分为以下三步(即非原子性操作)
① 取得原有i值
② 计算i-1
③ 对i进行赋值
synchronize可以在任意对象及方法上加锁,而加锁的这段代码称为“互斥区”或“临界区”
非线程安全主要是指多个线程对同一个对象中的同一个实例变量进行操作时会出现被更改,值不同步的情况,进而影响程序的执行流程。
println()方法在内部是同步的
isAlive()方法
测试线程是否处于活动状态,即线程已经启动尚未终止。线程处于正在运行或准备开始运行状态,就认为线程是“存活”的。
未完待续~