实现多线程
(1)
让子类extends Thread,然后重写run方法,调用run方法要用start方法(用JVM虚拟机执行才有多线程),直接调用run没有多线程
public class myThread extends Thread{
public myThread(){
}
public myThread(String name) {
super(name);
}
@Override
public void run() {
for (int i = 0; i<100;i++){
System.out.println(getName() + ":" + i);
}
}
}
(2)
创建类实现Runable,在main中创建Thread对象调用,传入的对象是Runable
获取名字和设置名字方法
myThread my1 = new myThread();
my1.setName("高铁");
System.out.println(my1.getName());
myThread my2 = new myThread("飞机");
my1.start();
my2.start();
// 返回当前线程
System.out.println(Thread.currentThread().getName());
设置线程优先级
优先级的设置范围在1-10之间,优先级高只意味着获取CPU的概率高,不一定跑的最快
System.out.println(my1.getPriority());
System.out.println(my2.getPriority());
my1.setPriority(10);
System.out.println(my1.getPriority());
守护线程:主线程执行完毕,JVM虚拟机退出,守护线程不再执行
join:先执行这个线程,执行完之后再执行其他线程
// 设置主线程
Thread.currentThread().setName("hh");
// 将my1,my2 设置为守护线程
my1.setDaemon(true);
my2.setDaemon(true);
my1.start();
my2.start();
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName()+":"+i);
}
解决数据问题
同步代发块
避免重复性和出现负数(在买票过程中的问题)
private Object object = new Object();
// 用synchronized (object) {}
// 其中object就相当于锁(只能有一个线程在里面操作)
同步方法
public synchronized void sellTicker() {}
// 锁是this
public static synchronized void sellTicker() {}
// 同步静态方法的锁是sellTicker.class
线程安全的类
StringBuffer sb = new StringBuffer(); // 推荐
// 和StringBuilder相当
Hashtable<String,String> ht = new Hashtable<>(); // 不推荐
// 和HashMap相当
Vector<String> vt = new Vector<>(); // 不推荐
// 和ArrayList相当
List<String> list = Collections.synchronizedList(new ArrayList<String>()); // 推荐
Map<String, String> stringStringMap = Collections.synchronizedMap(new HashMap<String, String>()); // 推荐
Lock锁
格式
private Lock lock = new ReentrantLock();
try {
lock.lock();
for (int i = 0; i < 100; i++) {
System.out.println(getName() + ":" + i);
}
} finally {
lock.unlock();
}
注:生产者和消费者案例
wait()
notify() 唤醒当前线程
notifyAll 唤醒所有线程
方法要用synchronized修饰