一、程序,进程和线程
程序:逻辑+数据,没有执行的指令序列和相关的数据的集合(如:qq.exe;磁盘上的可执行命令)
进程:正在执行的程序,进程占有资源(CPU,Memory,IO)
线程:是进程中并发运行的过程(共享进程资源)
同步:步调一致的顺序执行,如上公交车,一个一个上车
异步:步调不一致的同步执行,如:大家一起上卡车
线程:名词->类
1.Thread类中包含一个方法run()这个方法就是独立运行的过程(可用匿名内部类覆盖run())
2.Thread类中还包含方法start()用来启动独立运行的run()
创建一个线程:
1.覆盖Thread的run()方法,提供独立运行的过程(方式多种)
2.调用Thread实例的start()方法启动run()过程
实例:
public static void main(String[] args) {
MyThread t=new MyThread();
YourThread t2=new YourThread();
t.setDaemon(true);
t2.setPriority(Thread.MAX_PRIORITY-1);<span style="white-space:pre"> </span>//9
t.start(); //启动run方法
Thread.yield();<span style="white-space:pre"> </span>//当前线程让出处理器
t2.start();
System.out.println("Over");
}
}
//通过继承来覆盖run()方法
class MyThread extends Thread{
public void run(){
for(int i=0;i<100;i++){
System.out.println("我抽出皮筋做弹弓子,打你们家玻璃");
if(i%2==0){
Thread.yield();
}
}
}
}
class YourThread extends Thread{
public void run(){
for(int i=0;i<100;i++){
System.out.println("你干啥呢?");
}
}
}
二、线程
(一)线程状态:
1.new(新建)
2.Runnable
3.Running
4.Block
5.Died
(二)线程状态管理
1.Thread.yield()当前线程让出处理器(离开running),使当前线程进入Runnable等待
2.Thread.sleep(times)使当前线程从running放弃处理器进入Block状态,然后当休眠times这么多毫秒后,再返回到Runnable
3.如果其他线程打断当前线程的Block(sleep),就会发生InterruptedException
4.后台进程(守护线程,精灵线程)
java进程的结束,当所有前台线程都结束时,java进程结束。后台线程不管是否结束,都被停掉
t.setDaemon(true);//将t变成守护线程
实例:
public static void main(String[] args) {
Thread t=new Thread(){
public void run(){
for(int i=0;i<5;i++){
System.out.println("睡觉");
try{
Thread.sleep(1000);
}catch(InterruptedException e){
System.out.println("干啥呐");
break;
}
}
}
};
t.start();
for(int i=0;i<5;i++){
System.out.println("砸墙");
try{
Thread.sleep(500);
}catch(InterruptedException e){
e.printStackTrace();
}
}
System.out.println("砸穿了");
t.interrupt();//当前线程打断线程t的sleep
}
(三)线程的优先级
默认有10优先级,优先级高的线程获得执行的机会多,机会的多少不能通过代码干预。默认的优先级是5
(四)两种方式创建线程
1.继承Thread类
a.继承Thread类,覆盖run()方法提供并发运行的机会
b.创建这个类的实例
c.使用start()方法启动线程
2.实现Runnable接口
a.实现Runnable接口,实现run()方法,提供并发运行的过程
b.创建这个类的实例,用这个实例作为Thread构造器参数创建Thread类
c.使用start()方法启动线程
3.使用内部类创建线程
可以使用Thread.currentThread()方法获得当前线程的引用
实例:
public static void main(String[] args) {//匿名内部类来开线程
new Thread(){
public void run(){
for(int i=0;i<5;i++){
System.out.println("HEY");
}
}
}.start();
new Thread(new Runnable(){
public void run(){
for(int i=0;i<5;i++){
System.out.println("HEY");
}
}
}).start();
}
实例:
public class RunnableDemo {
public static void main(String[] args) {
Thread t1=new Thread(new Foo());
Thread t2=new Thread(new Foo());
Thread t3=new Thread(new Foo());
t1.start();
t2.start();
t3.start();
}
}
class Foo implements Runnable{
public void run(){
for(int i=0;i<5;i++){
System.out.println("HEY");
}
}
}
(五)线程同步
1.多个线程并发读写同一个临界资源时会发生线程安全问题
2.可以使用同步代码块解决同步读写临界资源,解决并发安全问题
3.a.同步代码块
synchronized(this){}
b.同步监视器是一个任意对象实例,是一个多个线程之间的互斥的锁机制,多个线程要使用同一个“监视器”实现同步互斥
c.常见写法:
synchronized(this){}
d.如果方法的全部过程需要同步,可简单使用synchronized修饰方法
实例:
public class SyncDemo {
int i=1;
Object monitor=new Object();
public synchronized int getNumber(){//public synchronized int getNumber=public int getNumber{synchronized(this)}
// synchronized (monitor){//加锁,同一把锁,也就是这个monitor要定义在前面,像我们这里写的那样,但显得比较不好,所以一般用this当锁
if(i==20){
throw new RuntimeException("Over");
}
try{
Thread.sleep(10);
}catch(InterruptedException e){
e.printStackTrace();
}
return i++;
//}
}
//两个线程并发
public void go(){//非静态方法,不能讲下面的代码直接放到main里面,因为静态方法不能调非静态方法
Thread t1=new MyThread();
Thread t2=new MyThread();
t1.start();
t2.start();
}
public static void main(String[] args) {
new SyncDemo().go();
}
class MyThread extends Thread{//使用内部类开线程
public void run(){
while(true){
System.out.println(getNumber());
}
}
}
}
java中同步的API:
1.StringBuffer是同步的 synchronized append()
StringBuilder不是同步的 append()
2.Vector和HashTable 同步
ArrayList和HashMap 不同步
3.Collection.synchronizedList()
ArrayList list=new ArrayList()
List syncList=Collection.synchronizedList(list);
(六)异步进程之间协作通信
1.同步写文件操作:从控制台读取一行,立即写到文件中
2.异步写文件操作,从控制台读取一行,放入到缓冲区,等到缓冲区满或者定时检查缓冲区,然后当缓冲区有内容的时候写入到文件中。
实例:
<span style="white-space:pre"> </span>WriteThread w=new WriteThread();
ReadThread r=new ReadThread();
List<String> buf=new ArrayList<String>();
class WriteThread extends Thread{
public void run(){
try{
PrintWriter out=new PrintWriter(
new FileWriter("unsyncio.txt",true));//追加方式打开
while(true){
if(buf.isEmpty()){
try{
Thread.sleep(5000);
}catch(InterruptedException e){}
continue;
}
// out.println(buf);//这里最好写一个迭代
for(String str:buf){
out.println(buf);
}
System.out.println("Writing...");
buf.clear();
out.close();
}
}catch(IOException e){
e.printStackTrace();
}
}
}
class ReadThread extends Thread{
public void run(){
BufferedReader console=
new BufferedReader(
new InputStreamReader(
System.in));
String str;
try{
while((str=console.readLine())!=null){
buf.add(str);
// w.interrupt();
if("exit".equalsIgnoreCase(str)){
w.interrupt();
break;
}
}
}catch(IOException e){
e.printStackTrace();
}
}
}
public void go(){
w.setDaemon(true);
w.start();
r.start();
}
public static void main(String[] args) {
new UnsyncIODemo().go();
}
三、Timer计时器
底层是一个线程
实例:
public static void main(String[] args) {
Timer t=new Timer();
t.schedule(new TimerTask(){
int i=10;
public void run(){
System.out.println("还有"+i--);
if(i==0){
t.cancel();
System.out.println("我还会回来的");
}
}
}, 1000,5000);
}