昨天外出了,没有更,老样子,思考小结。
线程可以彼此独立的执行,它是一种实现并发机制的有效手段,可以同时使用多个线程来完成不同的任务,并且一般用户在使用多线程时并不考虑底层处理的细节。
进程(process)是程序的一次执行过程,或是正在运行的一个程序。线程是比进程更小的程序执行单位,一个进程可以启动多个线程同时运行,不同线程之间可以共享相同的内存区域和数据。
有三种方式,如下所示:
(1)继承Thread类:编写简单,如果需要访问当前线程,则无需使用Thread.currentThread()方法,直接使用this即可获得当前线程。但线程类已经继承了Thread类,所以不能再继承其他父类。
(2)实现Runnable接口:避免由于Java单继承带来的局限性。但编程稍微复杂,如果要访问当前线程,则必须使用Thread.currentThread()方法。
(3)使用Callable接口和Future接口创建多线程:避免由于Java单继承带来的局限性,有返回值,可以抛出异常。但编程稍微复杂,如果要访问当前线程,则必须使用Thread.currentThread()方法。
线程从新建到死亡称为线程的生命周期,线程有新建(New)、就绪(Runnable)、运行(Running)、阻塞(Blocked)和死亡(Terminated)五种状态
启动一个线程是调用start()方法,使线程所代表的虚拟处理机处于可运行状态,这意味着它可以由JVM调度并执行。这并不意味着线程就会立即运行。run()方法可以产生必须退出的标志来停止一个线程。
不能,一个对象的一个synchronized方法只能由一个线程访问。
从宏观上看,多线程的并发运行时各个线程轮流获得CPU的使用权,分别执行各自的任务。但在运行池中,会有多个处于就绪状态的线程在等待CPU,java虚拟机的一项任务就是负责线程的调度,即按照特定的机制为多个线程分配CPU使用权。调度模型分为分时调度模型和抢占式调度模型两种。前者是让所有线程轮流获得CPU使用权,平均分配每个线程占用CPU的时间片。抢占式调度模型是优先让可运行池中优先级高的线程占用CPU,若运行池中线程优先级相同,则随机选择一个线程使用CPU当它失去CPU使用权时,在随机选取一个线程获取CPU使用权。JAVA默认使用抢占式调度模型。
/**
* 利用多线程,同时输出10以内的奇数和偶数,以及当前运行的线程名称,输出数字完毕输出end。
* 1.synchronized(obj){
* //同步代码块
* }
* 2.public synchronized void run() {
* //同步方法
* }
*/
public class nineA {
public static void main(String[] args) {
MyRunnable1 myRunnable1 = new MyRunnable1();
MyRunnable2 myRunnable2 = new MyRunnable2();
new Thread(myRunnable1,"线程偶数:").start();
new Thread(myRunnable2,"线程奇数:").start();
}
}
//线程1 偶数
class MyRunnable1 implements Runnable{
@Override
public synchronized void run() {
for (int i = 0; i <= 10; i++) {
if (i % 2 == 0){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
//currentThread()方法是在Thread类的静态方法,可以返回当前正在执行的线程对象的引用
System.out.println(Thread.currentThread().getName()+":"+i);
}
}
System.out.println(Thread.currentThread().getName()+"end");
}
}
//线程2 奇数
class MyRunnable2 implements Runnable{
@Override
public synchronized void run() {
for (int i = 0; i <= 10; i++) {
if (i % 2 != 0){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
//currentThread()方法是在Thread类的静态方法,可以返回当前正在执行的线程对象的引用
System.out.println(Thread.currentThread().getName()+":"+i);
}
}
System.out.println(Thread.currentThread().getName()+"end");
}
}
import java.util.Random;
/**
* 编写一个继承Thread类的方式实现多线程的程序,该类MyThread有两个属性:一个字符串WhoAmI代表线程名,
* 一个整数delay代表该线程随机要休眠的时间。利用有参的构造函数指定线程名称和休眠时间,休眠时间为随机数,
* 线程执行时,会显示线程名,和要休眠时间。最后,在main()方法中创建三个线程对象以展示执行情况。
*/
public class nineB {
public static void main(String[] args) {
Random random = new Random();
MyThread myThread1 = new MyThread("线程1",((int) (random.nextDouble() * 10000.0)));
MyThread myThread2 = new MyThread("线程1",((int) (random.nextDouble() * 10000.0)));
MyThread myThread3 = new MyThread("线程1",((int) (random.nextDouble() * 10000.0)));
myThread1.start();
myThread2.start();
myThread3.start();
}
}
class MyThread extends Thread{
private String WhoAmI;
private int delay;
public MyThread(String whoAmI, int delay) {
WhoAmI = whoAmI;
this.delay = delay;
}
@Override
public synchronized void run() {
try {
Thread.sleep(delay);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+":"+delay);
}
}
public class nineC {
public static void main(String[] args) {
TestDeadLock td1 = new TestDeadLock();
TestDeadLock td2 = new TestDeadLock();
td1.flag = 1;
td2.flag = 0;
new Thread(td1).start();
new Thread(td2).start();
}
}
class TestDeadLock implements Runnable{
public int flag = 1;
//static静态对象是类的所有对象共享的
// private static Object o1 = new Object();
// private static Object o2 = new Object();
private Object o1 = new Object();
private Object o2 = new Object();
@Override
public void run() {
System.out.println("flag="+flag);
if (flag == 1){
synchronized (o1){
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized(o2){
System.out.println("1");
}
}
}
if (flag == 0){
synchronized (o2){
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized(o1){
System.out.println("0");
}
}
}
}
}