/**
* 多线程的创建,方式一:继承于thread类
* 1,创建继承与thread类的子类
* 2,重写thread类的run()方法-->将此线程执行的操作生命在run()方法中
* 3,创建thread类的子类的对象
* 4,通过此对象调用start()方法
*<p>
*例子:遍历100以内的所有的偶数
*
* @author rieson
* @create 2020-12-22-9:26
*/
//1创建一个继承与Thread类的子类
class MyThread extends Thread{
//2重写run()方法
@Override
public void run() {
for (int i = 0; i < 100; i++) {
if (i %2==0) {
System.out.println(Thread.currentThread().getName()+""+i);
}
}
}
}
public class ThreadTest {
public static void main(String[] args) {
//3创建threadz子类的对象
MyThread myThread = new MyThread();
//4通过此对象调用start():1启动当前线程,2调用当前线程的run()
myThread.start();
//问题一:我们不能直接调用run()方法
//问题二:再启动一个线程,遍历100以内的偶数,不可以让已经start()线程再次执行,会报错
//我们需要重新创建一个线程的对象,让他再次调用start()
//如下操作仍然实在main线程中执行的
MyThread myThread1 = new MyThread();
myThread1.start();
for (int i = 0; i < 100; i++) {
if (i %2==0) {
System.out.println(i+"*");
}
}
}
}
/**
* 测试Thread类中的方法:
* 1,start():启动当前线程,调用当前线程的run()
* 2,run():通常需要重写Tread的类中的此方法,将要执行的操作定义在此方法中
* 3,currentThread:静态方法,返回执行当前代码的线程
* 4,getName():获取当前线程的名称
* 5,setName():设置当前线程的名称
* 6,yield():释放当前线程执行权
* 7,join():线程a中调用线程b中join方法时,a线程就会进入阻塞状态,直到b线程执行完毕后再结束阻塞状态
* 8,stop():强制结束当前线程,已过时,不建议使用
* 9,sleep(long milltime):线程睡眠指定的毫秒数,
* 10,idAlive():判断当前线程是否还存活
*
*
*
* 线程的优先级:
* 1,略
*
* 2,如何获取和设置线程的优先级
* getPriority():获取线程的优先级
* setPriority(int p):设置线程的优先级
*
*
*
* @author rieson
* @create 2020-12-22-10:46
*/
class MyTreadmethod extends Thread {
@Override
public void run() {
for (int i = 0 ; i < 100; i++) {
if (i % 2 == 0) {
// try {
// // sleep(1000);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
System.out.println(Thread.currentThread().getName()+Thread.currentThread().getPriority()+":" + "" + i);
}
if (i % 20 == 0) {
yield();
}
}
}
public MyTreadmethod(String name) {
super(name);
}
}
public class ThreadMethodTest {
public static void main(String[] args) {
MyTreadmethod myTreadmethod = new MyTreadmethod("Thread: 1");
// myTreadmethod.setName("线程一");
myTreadmethod.start();
myTreadmethod.setPriority(Thread.MAX_PRIORITY);
//主线程命名
Thread.currentThread().setName("主线程");
for (int i = 0; i < 100; i++) {
if (i % 2 == 0) {
System.out.println(Thread.currentThread().getName() + "" + i);
}
// if (i ==20) {
// try {
// myTreadmethod.join();
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// }
}
}
}
/**
* 创建多线程的方法二:
* 1,创建一个实现Runnable()接口的类
* 2,实现类去实现Runnable中的抽象方法
* 3,创建实现类的对象
* 4,将此对象作为参数传递到Thread类的构造器中,创建Thread的对象
* 5,通过Thread类的对象来调用start()方法
*
* @author rieson
* @create 2020-12-22-12:38
*/
//1,创建一个实现Runnable()接口的类
class RunNable implements Runnable{
// int s;
// public RunNable(int s){
// this.s=s;
// }
@Override
public void run() {
for (int i = 0; i < 100; i++) {
if (i % 2 == 0) {
System.out.println(i);
}
}
}
}
public class ThreadTest1 {
public static void main(String[] args) {
//3,创建实现类的对象
RunNable runNable = new RunNable();
//4,将此对象作为参数传递到Thread类的构造器中,创建Thread的对象
new Thread(runNable).start();
new Thread(runNable).start();
}
}
/**
*例子:创建三个窗口卖票,总票数为100张,使用实现Ruunable接口的方式
* 1,创建一个实现Runnable接口类
* 2,实现类实现run()方法
* 3,创建实现类对象
* 4,将此对象作为参数传递到Thread类构造器中,创建Thread类的对象
* 5,调用Thread类中的start()方法
*
* 比较创建线程的两种方法
* 开发中优先选择Ruunable接口的方法:
* 1,实现的方式没有类的单继承得局限性
* 2,实现方式更适合处理多个线程有共享数据的情况
* 联系:thread也继承了Runnable方法
* 相同的点都是重写run(),将要执行的逻辑代码都是放在run()中
* @author rieson
* @create 2020-12-22-13:13
*/
class Window1 implements Runnable{
private int stick =100;
@Override
public void run() {
while (true){
if (stick>0) {
System.out.println(Thread.currentThread().getName() + "卖了多少票号:" + stick);
stick--;
}else{
break;
}
}
}
}
public class WindowTest1 {
public static void main(String[] args) {
Window1 window1 = new Window1();
Thread t1= new Thread(window1);
t1.start();
t1.setName("窗口一:");
Thread t2= new Thread(window1);
t2.start();
t2.setName("窗口二:");
Thread t3= new Thread(window1);
t3.start();
t3.setName("窗口三:");
}
}
/**
*例子:创建三个窗口卖票,总票数为100张,使用实现Ruunable接口的方式
* 1,创建一个实现Runnable接口类
* 2,实现类实现run()方法
* 3,创建实现类对象
* 4,将此对象作为参数传递到Thread类构造器中,创建Thread类的对象
* 5,调用Thread类中的start()方法
* 比较创建线程的两种方法
* 开发中优先选择Ruunable接口的方法:
* 1,实现的方式没有类的单继承得局限性
* 2,实现方式更适合处理多个线程有共享数据的情况
* 联系:thread也继承了Runnable方法
* 相同的点都是重写run(),将要执行的逻辑代码都是放在run()中
*
*
*
* -------------------------------------------------------
* 1,问题:买票过程中出现了重票和,错票的 所谓的线程安全问题
* 2,出现的原因,阻塞状态时,多个线程同时操作到同一个票
* 3,如何解决:等第一个线程操作共享数据时,其他线程不能参与进来,直到此线程操作完成时,其他线程才能操作
* 即使是阻塞状态时,也是如此
* 4,在JAVA中,通过同步机制,来解决线程安全问题
* 方式一:同步代码块
* synchronized(同步监视器){
* //需要被同步的代码
*
* }
* 说明:操作共享数据的代码 = 需要被同步的代码 --->不能包含多了,也不能包含少了
* 共享数据 = 多个线程共同操作的数据
* 同步监视器 = 锁:任何一个对象都可以充当锁
* 要求:多个线程必须共用同一把锁
* 说明:在继承Tread类,创建多线程的方式,我们可以考虑使用this充当同步监视器
*
* 方式二:同步方法
* 给共享代码块,写在一个方法中,用synchrnoized 定义此方法。
* 方式三:同步锁
* eg:1,面试题:synchronized 与同步锁的异同?
* 同:都可以解决线程安全问题
* 不同:synchronized 机制再执行玩同步代码后,自动释放同步监视器
* lock需要手动的释放调用(unlock)
* 2,如何解决线程安全问题?有哪几种方式?
* 答:同步代码块,同步方法,同步锁
*5,同步的方式:解决掉了线程安全的问题----好处
* 操作代码时,只能由一个线程操作,其他线程等待,相当于是一个单线程,效率低
*
*
*
*
*
*
* @author rieson
* @create 2020-12-22-13:13
*/
class Window1 implements Runnable{
String z = "asd";
private int stick =100;
//1,实例化
private ReentrantLock lock=new ReentrantLock();
@Override
public void run() {
while (true){
try {
lock.lock();
if (stick>0) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "卖了多少票号:" + stick);
stick--;
}else{
break;
}
}finally{
lock.unlock();
}
}
}
}
//方式一
// @Override
// public void run() {
// while (true){
// //用当前对象去充当
// synchronized (this){
// if (stick>0) {
// try {
// Thread.sleep(100);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// System.out.println(Thread.currentThread().getName() + "卖了多少票号:" + stick);
// stick--;
// }else{
// break;
// }
// }
// }
//
//
// }
//}
class Test{
}
public class WindowTest1 {
public static void main(String[] args) {
Window1 window1 = new Window1();
Thread t1= new Thread(window1);
t1.start();
t1.setName("窗口一:");
Thread t2= new Thread(window1);
t2.start();
t2.setName("窗口二:");
Thread t3= new Thread(window1);
t3.start();
t3.setName("窗口三:");
}
}
2020-12-26 Java多线程学习总结
最新推荐文章于 2021-03-02 14:29:47 发布