今天学习了一下多线程,现在总结一下
首先要理解,程序 ---- 进程------线程 这三者之间的关系。
程序就是我们所执行的“代码”,进程就是正在进行的程序。而线程呢就是在一个进程中的一个执行路径。如果一个进程可以同时进行多个线程,那说明支持多线程。
其实实际上,一个cpu在同一时间只能执行一个线程,而且在多线程时,因为需要各个线程的来回切换,完成的时间要比单线程还要慢。不过即使这样,多线程也有很多优点,比如可以提前计算机的cpu利用率,而且可以增强用户的体验。可以让用户在同一时间进行多种任务。
创建多线程的方式有两种,第一种就是类直接继承Thread类,并重写run()方法,然后创建该类的实例并调用start()方法即可。这种方法有局限性,就是因为java是单继承的。不过有第二种方法,就是实现runnable接口方法,实现里面的run()方法。而启动该线程时,除了创建该类的实例外,还要创建Thread的实例,并把该类的实例作为参数传入Thread的构造器中,调用Thread的实例的start()方法才行。例如:
Class Test implements Runnable{
public void run(){
//这里面写线程执行语句。
}
}
在别的类方法中调用 Test线程时:
Test test = new Test();
Thread th = new Thread(test);
th.start();
这样既可。
然后就是一些多线程的方法,有sleep(),join(),yield()后面还有wait()(暂时没学到)。sleep()和 join() 方法都是对线程的一种阻塞,sleep()方法必须传入参数,指代该线程的睡眠的时间,单位是毫秒。 join()方法可以不传入参数,如果没有参数,代表该线程执行完毕后再执行以下内容。然后对应的有interrupt()方法,这个方法可以直接结束该线程的阻塞状态,直接运行。下面有个例题,方便理解。
代码要求:编写程序,在main方法中创建一个线程。线程每隔一定时间(200ms以内的随机时间)产生一个0-100之间的随机整数,打印后将该整数放到集合中;
共产生100个整数,全部产生后,睡眠30秒,然后将集合内容打印输出;
在main线程中,唤醒上述睡眠的线程,使其尽快打印集合内容。
代码如下。
package com.xiubo.javase.test;
public class Test4 {
public static void main(String[] args) {
InterTest it = new InterTest();
Thread t = new Thread(it);
t.start();
while(t.isAlive()){
if(it.id == 5){
t.interrupt();
}
}
}
}
package com.xiubo.javase.test;
import java.util.ArrayList;
import java.util.List;
public class InterTest implements Runnable {
int id = 0;
int sleepTime = 0;
List<Integer> list = new ArrayList<Integer>();
@Override
public void run() {
for (int i = 0; i < 100; i++) {
sleepTime = (int) (Math.random() * 201);
try {
Thread.sleep(sleepTime);
} catch (InterruptedException e) {
// e.printStackTrace();
}
int num = (int) (Math.random() * 101);
System.out.println(num);
list.add(num);
}
id = 5;
try {
Thread.sleep(30000);
} catch (InterruptedException e) {
// e.printStackTrace();
}
System.out.println(list);
}
}
然后就是线程同步问题了,线程安全一般是为了防止在访问一些共享数据时,因为同时进入而造成程序的混乱。这就需要一个锁,这个锁的作用就是,在该线程还没有完成对共享数据访问并修改之前,别的线程也无法进入。这样确保了数据的正确性。线程安全问题很重要,比如大家买车票,下面也附上一个代码,方便理解。代码完成的是模拟一个售票系统,同时有三个窗口卖100张票。
package com.xiubo.javase.test;
public class Test5 {
public static void main(String[] args) {
Window w1 = new Window();
Thread t1 = new Thread(w1,"1号窗口");
t1.start();
Thread t2 = new Thread(w1,"2号窗口");
t2.start();
Thread t3 = new Thread(w1,"3号窗口");
t3.start();
}
}
package com.xiubo.javase.test;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Window implements Runnable {
int ticket = 100;
Lock lock = new ReentrantLock();
boolean flag = true;
@Override
public void run() {
while (flag) {
try {
Thread.sleep(3);
} catch (InterruptedException e) {
//e.printStackTrace();
}
lock.lock();
if (ticket > 0) {
System.out.println(Thread.currentThread().getName() + "售票,余票为:" + --ticket);
}
if(ticket == 0){
flag = false;
}
lock.unlock();
}
}
}
好的,今天就到这儿了,感觉多线程还可以,换了个新老师,讲的很快,学的东西很多,很充实,要加油跟上不掉队!
<!--EndFragment-->