Java多线程
一、创建多线程的3种方式
分别是继承线程类,实现Runnable接口,匿名类
1.继承线程类
(1)extends Thread
(2)在类中重写run方法
(3)创建对象,然后对象.start方法开启线程
public class Hero extends Thread{
String name;
Hero(String name){
this.name=name;
}
public void run() {
try {
Thread.sleep(5000);
}catch(Exception e) {
e.printStackTrace();
}
System.out.println(name);
}
}
public class Test{
public static void main(String[] args) {
Hero h1=new Hero("线程1");
h1.start();
Hero h2=new Hero("线程2");
h2.start();
System.out.println("结束");;
}
}
运行结果:
从调试中可以看到,在main中有一个主线程,然后创建了两个子线程。
————————————————
2.实现Runnable接口
(1)一个类实现Runnable接口,即implement Runnable
(2)重写run方法
(3)创建这个类的对象Hero h1=new Hero();
(4)Thread t1=new Thread(h1)
(5)t1.start();开启线程
public class Hero implements Runnable{
//不变
}
public static void main(String[] args) {
Hero h1=new Hero("线程1");
Hero h2=new Hero("线程2");
Thread t1=new Thread(h1);
Thread t2=new Thread(h2);
//t1.setName("t1");
//t2.setName("t2");
t1.start();
t2.start();
System.out.println("结束");;
}
运行结果:
————————————————
3.匿名类
(1)Thread t1=new Thread(){ Public void run(){ } };
(2)t1.start();开启线程
这里让线程休眠了5秒,不然跑太快截图不到两个线程
public class Test{
public static void main(String[] args) {
Thread t1=new Thread() {
public void run() {
try {
Thread.sleep(5000);
}catch(Exception e ) {
e.printStackTrace();
}
System.out.println("线程1");
}
};
t1.start();
Thread t2=new Thread() {
public void run() {
try {
Thread.sleep(5000);
}catch(Exception e ) {
e.printStackTrace();
}
System.out.println("线程2");
}
};
t2.start();
System.out.println("结束");;
}
}
运行结果:
==================================================分割线
二、常用方法
(1)sleep:线程休眠
(2)Join:在main中有一个主线程,可以把子线程加入到当前main的线程中相当于提高优先级
(3)线程优先级:
t1.setPriority(Thread.MAX_PRIORITY);
t2.setPriority(Thread.MIN_PRIORITY);
(4)yield:书里说是叫线程礼让,也就是让线程临时暂停一下,让别的线程
(5)setDaemon(守护线程):业务线程都执行完之后,不管守护线程,直接关闭当前进程。
==================================================分割线
三、线程同步
1.同步块(临界区)
为了解决同步问题,用到synchronized。书上使用的是(“”),在网上看的是使用同步对象lock,都可以锁住。
package test;
public class Hero extends Thread{
String name;
//final static Object lock=new Object();
Hero(String name){
this.name=name;
}
public void run() {
System.out.println(name+"尝试进入临界区");
synchronized("") {
System.out.println(name+"进入了临界区");
try {
Thread.sleep(10000);
}catch(Exception e) {
e.printStackTrace();
}
}
System.out.println(name+"退出了临界区");
}
}
public class Test{
public static void main(String[] args) {
Hero h1=new Hero("线程1");
Hero h2=new Hero("线程2");
h1.start();
h2.start();
System.out.println("结束");;
}
}
运行结果:
2.同步方法
就是在方法前面修饰synchronize关键字的方法。
3.线程安全的类
如果一个类里面的方法都是被synchronize修饰的,那么这个类就是线程安全的。
四、线程安全有关
1.HashMap和Hashtable的区别
HashMap和Hashtable都实现了Map接口,都是键值对保存数据的方式
区别1:
HashMap可以存放 null
Hashtable不能存放null
区别2:
HashMap不是线程安全的类
Hashtable是线程安全的类
2.StringBuffer和StringBuilder的区别
StringBuffer 是线程安全的
StringBuilder 是非线程安全的
所以当进行大量字符串拼接操作的时候,如果是单线程就用StringBuilder会更快些,如果是多线程,就需要用StringBuffer 保证数据的安全性
3.ArrayList和Vector的区别
通过在eclipse中查看源代码可以得知:
ArrayList类的声明:
public class ArrayList extends AbstractList
implements List, RandomAccess, Cloneable, java.io.Serializable
Vector类的声明:
public class Vector extends AbstractList
implements List, RandomAccess, Cloneable, java.io.Serializable
他们的区别也在于,Vector是线程安全的类,而ArrayList是非线程安全的。
4.把非线程安全的集合转换为线程安全
rrayList是非线程安全的,换句话说,多个线程可以同时进入一个ArrayList对象的add方法。
借助Collections.synchronizedList,可以把ArrayList转换为线程安全的List。
与此类似的,还有HashSet,LinkedList,HashMap等等非线程安全的类,都通过工具类Collections转换为线程安全的
未完待续
不得不说,看书真是不够的,书上讲完了同步就没了,非常简略,看了网站学习的才知道还有这么多,后面还有死锁,交互,线程池,LOCK对象和院子访问。。。。。没时间看了,先写到这把,一堆作业啥的没写,以后再补上,下次一定。