Thread类中的构造方法和常用方法:
构造方法:public Thread() 和 public Thread(Runnable target)
常用方法:start() 开启线程 和 getName() 获取线程名字,线程名字的默认编号是Thread-编号,编号是默认从0开始 currentThread()是Thread的静态方法,获取当前线程对象
多线程安全问题:
概述:多线程并发操作统一数据,此时就有可能出现安全问题,此时需要使用同步来解决。
同步:进程进入了以后,进程没有执行执行完枷锁的代码块,剩下的进程都不能进入
同步代码块:
格式:
synchronized(锁对象){
要加锁的代码
}
1、同步代码块的锁对象可以是任意类型的对象
2、必须使用同一把锁,不然会出现锁不住的情况
此时我们会把锁对象设置为当前的字节码文件,
因为无论哪一个,其对应的字节码文件只有一份
同步方法:—具体写入到这里了,哈哈哈>>>>有关同步方法具体相关点击这里
非静态同步方法:锁对象是this
静态同步方法:锁对象是该类的字节码文件对象(该类名.class)
线程安全,效率会低。
案例代码:
package thread;
public class ThreadTickts {
public static void main(String[] args) {
//创建多个线程
MyThread1 mt1 = new MyThread1("窗口1");
MyThread1 mt2 = new MyThread1("窗口2");
MyThread1 mt3 = new MyThread1("窗口3");
MyThread1 mt4 = new MyThread1("窗口4");
mt1.start();
mt2.start();
mt3.start();
mt4.start();
}
}
/*
* 出现安全问题,票数大时,出现的概率大,所以这里加入线程休眠来模拟出现问题的情况
* 票数出现负值:当票数为1的时候,刚好窗口1-4都是休眠状态,此时休眠结束后,直接往下执行
* 此时已经跳过了if判断,所以窗口1-4都会继续输出
* 票数出现重复值:问题出现在tickts--,因为有可能在tickts-1的时候,cpu资源被别人抢走
* 此时tickts虽然-1,但是却没有重新赋给tickts
*
*/
class MyThread1 extends Thread{
//切记,此时的tickts一定要定义为static的,即是四个窗口共享100张票
//如果没有定义为static,则会每个窗口都会分别出售100张票
static int tickts=100;
public MyThread1() {
super();
}
public MyThread1(String name) {
super(name);
}
@Override
public void run() {
while(true){
synchronized (ThreadTickts.class) {
if(tickts<1){
break;
}
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(getName()+"----正在卖"+ tickts-- +"张票");
}
}
}
}
方式二案例:
package thread;
public class ThreadTickts2 {
public static void main(String[] args) {
//创建Runnable接口的子类对象
MyRunnable1 mr = new MyRunnable1();
//创建线程对象
Thread th1 = new Thread (mr,"窗口1");
Thread th2 = new Thread (mr,"窗口2");
Thread th3 = new Thread (mr,"窗口3");
Thread th4 = new Thread (mr,"窗口4");
th1.start();
th2.start();
th3.start();
th4.start();
}
}
class MyRunnable1 implements Runnable{
//此时不需要加static,因为Runnable接口的子类对象只创建一个
int tickts=100;
//构造方法也不用重写,因为开启的线程对象就是Thread,
//不像继承Thread方式那样去调用父类的构造
@Override
public void run() {
while(true){
synchronized (ThreadTickts.class) {
if(tickts<1){
break;
}
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
//currentThread()是Thread的静态方法,获取当前线程对象
System.out.println(Thread.currentThread().getName()+"----正在卖"+ tickts-- +"张票");
}
}
}
}